]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7678 server-side stateless settings
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 31 Aug 2016 14:05:43 +0000 (16:05 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Tue, 6 Sep 2016 08:13:55 +0000 (10:13 +0200)
* Settings class becomes abstract as multiple implementations
are used. Can't become an interface for binary
backward-compatibility of API

* tests should use MapSettings, an in-memory implementation
of Settings

* web server uses a thread-specific cache of settings when
processing HTTP requests

* web server does not have a cache of settings during startup,
except for the system settings loaded from sonar.properties

* Compute Engine uses a thread-specific cache of settings when
  processing a task. Cache is clear at end of task.

 * some useless methods of PersistentSettings are removed

194 files changed:
it/it-plugins/security-plugin/src/test/java/FakeAuthenticatorTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/XooTokenizerTest.java
server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
server/sonar-server/src/main/java/org/sonar/ce/settings/ComputeEngineSettings.java [deleted file]
server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectSettings.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectSettingsFactory.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/ce/settings/SettingsLoader.java
server/sonar-server/src/main/java/org/sonar/ce/settings/ThreadLocalSettings.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/authentication/JwtSerializer.java
server/sonar-server/src/main/java/org/sonar/server/authentication/UserSessionInitializer.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/SettingsRepositoryImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/taskprocessor/ReportTaskProcessor.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java
server/sonar-server/src/main/java/org/sonar/server/platform/PersistentSettings.java
server/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/ServerSettingsImpl.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/platform/StartupMetadataPersister.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel2.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel3.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGates.java
server/sonar-server/src/main/java/org/sonar/server/setting/DatabaseSettingLoader.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/setting/DatabaseSettingsEnabler.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/setting/NopSettingLoader.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/setting/ProjectSettingsFactory.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/setting/SettingLoader.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
server/sonar-server/src/main/java/org/sonar/server/user/DoPrivileged.java
server/sonar-server/src/main/java/org/sonar/server/user/SecurityRealmFactory.java
server/sonar-server/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java
server/sonar-server/src/main/java/org/sonar/server/user/UserSessionFilter.java
server/sonar-server/src/test/java/org/sonar/ce/http/CeHttpClientTest.java
server/sonar-server/src/test/java/org/sonar/ce/settings/ComputeEngineSettingsTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/ce/settings/SettingsLoaderTest.java
server/sonar-server/src/test/java/org/sonar/server/activity/ActivityServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/activity/index/ActivityIndexDefinitionTest.java
server/sonar-server/src/test/java/org/sonar/server/activity/index/ActivityIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/app/ProcessCommandWrapperImplTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/JwtHttpHandlerTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/JwtSerializerTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/RealmAuthenticatorTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/UserIdentityAuthenticatorTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/UserSessionInitializerTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/ws/LoginActionTest.java
server/sonar-server/src/test/java/org/sonar/server/authentication/ws/ValidateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java
server/sonar-server/src/test/java/org/sonar/server/batch/UsersActionTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/configuration/CeConfigurationImplTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/dbcleaner/ProjectCleanerTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/api/measurecomputer/MeasureComputerContextImplTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/SettingsRepositoryTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/duplication/IntegrateCrossProjectDuplicationsTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/DebtCalculatorTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/DefaultAssigneeTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoaderTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/filter/IssueFilterTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/RatingSettingsTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/ApplyPermissionsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/IndexTestsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/LoadPeriodsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PurgeDatastoresStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/QualityGateLoadingStepTest.java
server/sonar-server/src/test/java/org/sonar/server/email/ws/UpdateConfigurationActionTest.java
server/sonar-server/src/test/java/org/sonar/server/es/EsClientProviderTest.java
server/sonar-server/src/test/java/org/sonar/server/es/EsTester.java
server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java
server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueAuthorizationIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDebtTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexDefinitionTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/MetricsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/measure/custom/ws/UpdateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/notification/NotificationServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SetDefaultTemplateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/PersistentSettingsTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ServerIdLoaderTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ServerImplTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ServerLoggingTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/platform/StartupMetadataPersisterTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/StartupMetadataProviderTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/UrlSettingsTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/cluster/ClusterImplTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/db/EmbeddedDatabaseFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/db/EmbeddedDatabaseTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/EsMonitorTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SettingsMonitorTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/monitoring/SonarQubeMonitorTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/ws/RestartActionTest.java
server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkDeleteActionTest.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/DeleteActionTest.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/QualityGatesTest.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/DeselectActionTest.java
server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/index/ActiveRuleIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangelogActionTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexDefinitionTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingsEnablerTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/setting/NopSettingLoaderTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/setting/ProjectSettingsFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/setting/ThreadLocalSettingsTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java
server/sonar-server/src/test/java/org/sonar/server/test/index/TestIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/test/index/TestIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/test/ws/ListActionTest.java
server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java
server/sonar-server/src/test/java/org/sonar/server/ui/ws/GlobalNavigationActionTest.java
server/sonar-server/src/test/java/org/sonar/server/ui/ws/SettingsNavigationActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/SecurityRealmFactoryTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ThreadLocalUserSessionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/UserSessionFilterTest.java
server/sonar-server/src/test/java/org/sonar/server/user/UserUpdaterTest.java
server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexDefinitionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexerTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/ChangePasswordActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/DeactivateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java
server/sonar-server/src/test/java/org/sonar/server/user/ws/UpdateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/usergroups/ws/DeleteActionTest.java
server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexDefinitionTest.java
server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java
sonar-core/src/test/java/org/sonar/core/timemachine/PeriodsTest.java
sonar-core/src/test/java/org/sonar/core/util/DefaultHttpDownloaderTest.java
sonar-db/src/test/java/org/sonar/db/DefaultDatabaseTest.java
sonar-db/src/test/java/org/sonar/db/TestDb.java
sonar-db/src/test/java/org/sonar/db/permission/PermissionRepositoryTest.java
sonar-db/src/test/java/org/sonar/db/purge/PurgeConfigurationTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
sonar-plugin-api/src/main/java/org/sonar/api/config/Encryption.java
sonar-plugin-api/src/main/java/org/sonar/api/config/MapSettings.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/config/Settings.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectBuilderTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/cpd/internal/DefaultCpdTokensTest.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/sensor/internal/SensorContextTesterTest.java
sonar-plugin-api/src/test/java/org/sonar/api/config/EmailSettingsTest.java
sonar-plugin-api/src/test/java/org/sonar/api/config/MapSettingsTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java [deleted file]
sonar-plugin-api/src/test/java/org/sonar/api/scan/filesystem/FileExclusionsTest.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/DurationsTest.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalSettings.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleSettings.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectSettings.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/ProjectConfiguratorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/BatchPluginPredicateTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/FileCacheProviderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/DefaultCpdBlockIndexerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/JavaCpdBlockIndexerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueExclusionPatternInitializerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/pattern/IssueInclusionPatternInitializerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/DefaultPostJobContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/postjob/PostJobOptimizerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ReportPublisherTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/QProfileVerifierTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/rule/RulesProfileProviderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/LanguageVerifierTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleSettingsTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectSettingsTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ExclusionFiltersTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactoryTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionFactoryTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/ConsoleReportTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorContextTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorOptimizerTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/coverage/CoverageExclusionsTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/source/SymbolizableBuilderTest.java

index 6a0b1884a057a617e6893ab7b368ea28e9c170d4..577033fe27d09764364f704359441ea7b1a0ad4e 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
+
 import java.util.Map;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.security.UserDetails;
 
@@ -33,7 +35,7 @@ public class FakeAuthenticatorTest {
 
   @Before
   public void setUp() {
-    settings = new Settings();
+    settings = new MapSettings();
     authenticator = new FakeAuthenticator(settings);
     authenticator.init();
   }
index aaae76aa4750af532c31491440e3662c8bfc3ea5..a5741a255f03f2309d0259a18d2306eb8c2970da 100644 (file)
@@ -34,6 +34,7 @@ import org.sonar.api.config.Settings;
 
 import java.io.File;
 import java.io.IOException;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -54,7 +55,7 @@ public class XooTokenizerTest {
     baseDir = temp.newFolder();
     fileSystem = new DefaultFileSystem(baseDir.toPath());
     when(context.fileSystem()).thenReturn(fileSystem);
-    settings = new Settings();
+    settings = new MapSettings();
     when(context.settings()).thenReturn(settings);
   }
 
index fff798be3cf45fcc0afeee7b52ec80dae6539e31..a6a97ed4abefcf115b2eea26cf1a949f9f7e35c5 100644 (file)
@@ -46,7 +46,7 @@ import org.sonar.ce.CeTaskCommonsModule;
 import org.sonar.ce.db.ReadOnlyPropertiesDao;
 import org.sonar.ce.es.EsIndexerEnabler;
 import org.sonar.ce.platform.ComputeEngineExtensionInstaller;
-import org.sonar.ce.settings.ComputeEngineSettings;
+import org.sonar.ce.settings.ProjectSettingsFactory;
 import org.sonar.ce.user.CeUserSession;
 import org.sonar.core.component.DefaultResourceTypes;
 import org.sonar.core.config.CorePropertyDefinitions;
@@ -101,7 +101,6 @@ import org.sonar.server.notification.email.AlertsEmailTemplate;
 import org.sonar.server.notification.email.EmailNotificationChannel;
 import org.sonar.server.platform.DatabaseServerCompatibility;
 import org.sonar.server.platform.DefaultServerUpgradeStatus;
-import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.platform.ServerFileSystemImpl;
 import org.sonar.server.platform.ServerImpl;
 import org.sonar.server.platform.ServerLifecycleNotifier;
@@ -131,7 +130,9 @@ import org.sonar.server.rule.RuleRepositories;
 import org.sonar.server.rule.index.RuleIndex;
 import org.sonar.server.rule.index.RuleIndexer;
 import org.sonar.server.search.EsSearchModule;
-import org.sonar.server.setting.ProjectSettingsFactory;
+import org.sonar.server.setting.DatabaseSettingLoader;
+import org.sonar.server.setting.DatabaseSettingsEnabler;
+import org.sonar.server.setting.ThreadLocalSettings;
 import org.sonar.server.startup.LogServerId;
 import org.sonar.server.test.index.TestIndexer;
 import org.sonar.server.user.DefaultUserFinder;
@@ -208,11 +209,10 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
   private static Object[] level1Components() {
     Version apiVersion = ApiVersion.load(System2.INSTANCE);
     return new Object[] {
-      ComputeEngineSettings.class,
+      ThreadLocalSettings.class,
       new SonarQubeVersion(apiVersion),
       SonarRuntimeImpl.forSonarQube(ApiVersion.load(System2.INSTANCE), SonarQubeSide.COMPUTE_ENGINE),
       UuidFactoryImpl.INSTANCE,
-      UrlSettings.class,
       ClusterImpl.class,
       DefaultDatabase.class,
       DatabaseChecker.class,
@@ -248,6 +248,10 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
 
   private static Object[] level2Components() {
     return new Object[] {
+      DatabaseSettingLoader.class,
+      DatabaseSettingsEnabler.class,
+      UrlSettings.class,
+
       // add ReadOnlyPropertiesDao at level2 again so that it shadows PropertiesDao
       ReadOnlyPropertiesDao.class,
       DefaultServerUpgradeStatus.class,
@@ -270,7 +274,6 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {
   private static Object[] level3Components() {
     return new Object[] {
       new StartupMetadataProvider(),
-      PersistentSettings.class,
       UriReader.class,
       ServerImpl.class
     };
index 98e1ba5c1e99b691b9d637194afe508666e3a19f..6bf1b1a3da7d23a3c2380967f98a6d87f7ca477f 100644 (file)
@@ -97,15 +97,15 @@ public class ComputeEngineContainerImplTest {
     );
     assertThat(picoContainer.getParent().getComponentAdapters()).hasSize(
       CONTAINER_ITSELF
-        + 4 // level 3
+        + 3 // level 3
     );
     assertThat(picoContainer.getParent().getParent().getComponentAdapters()).hasSize(
       CONTAINER_ITSELF
-        + 11 // level 2
+        + 14 // level 2
     );
     assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize(
       COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION
-        + 25 // level 1
+        + 24 // level 1
         + 49 // content of DaoModule
         + 2 // content of EsSearchModule
         + 54 // content of CorePropertyDefinitions
diff --git a/server/sonar-server/src/main/java/org/sonar/ce/settings/ComputeEngineSettings.java b/server/sonar-server/src/main/java/org/sonar/ce/settings/ComputeEngineSettings.java
deleted file mode 100644 (file)
index 4d821b4..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.ce.settings;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.Maps;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.Encryption;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.db.DbClient;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.server.platform.ServerSettings;
-
-import static com.google.common.base.Preconditions.checkState;
-
-/**
- * This class implements ServerSettings and extends Settings so that it can be injected in any component depending upon
- * either ServerSettings or Settings.
- *
- * <p>
- * In order to honor both Settings and ThreadLocalSettings contracts, none of the code inherited from the Settings super
- * class is actually used. Every public method of Settings is override and their implementation is delegated to
- * an inner object which can either be the default one or one specific to the current Thread. Selected of the inner
- * object will depend on whether the current Thread made use of method {@link #load()} or not. This approach also greatly
- * simplifies delegation code (see {@link #currentDelegate()}).
- * </p>
- */
-public class ComputeEngineSettings extends Settings implements ThreadLocalSettings, ServerSettings {
-  private final ServerSettings defaultDelegate;
-  private final ThreadLocal<ServerSettings> threadLocalDelegate = new ThreadLocal<>();
-
-  private final Properties rootProperties;
-  private final ComponentContainer componentContainer;
-  // we can't get injected with DBClient because it creates a circular dependency
-  private volatile DbClient dbClient;
-
-  public ComputeEngineSettings(PropertyDefinitions definitions, Properties rootProperties, ComponentContainer componentContainer) {
-    super(definitions);
-    this.rootProperties = rootProperties;
-    this.componentContainer = componentContainer;
-
-    this.defaultDelegate = new ServerSettingsImpl(definitions, rootProperties);
-  }
-
-  @Override
-  public void load() {
-    checkState(
-      this.threadLocalDelegate.get() == null,
-      "loadLocal called twice for Thread '%s' or state wasn't cleared last time it was used",
-      Thread.currentThread().getName());
-    this.threadLocalDelegate.set(loadServerSettings());
-  }
-
-  @Override
-  public void unload() {
-    this.threadLocalDelegate.remove();
-  }
-
-  private ServerSettings loadServerSettings() {
-    ServerSettings res = new ServerSettingsImpl(this.definitions, this.rootProperties);
-    Map<String, String> databaseProperties = Maps.newHashMap();
-    for (PropertyDto property : getDbClient().propertiesDao().selectGlobalProperties()) {
-      databaseProperties.put(property.getKey(), property.getValue());
-    }
-    res.activateDatabaseSettings(databaseProperties);
-    return res;
-  }
-
-  private DbClient getDbClient() {
-    if (dbClient == null) {
-      this.dbClient = componentContainer.getComponentByType(DbClient.class);
-    }
-    return dbClient;
-  }
-
-  private ServerSettings currentDelegate() {
-    return MoreObjects.firstNonNull(threadLocalDelegate.get(), defaultDelegate);
-  }
-
-  private Settings currentSettings() {
-    return currentDelegate().getSettings();
-  }
-
-  @Override
-  public ServerSettings activateDatabaseSettings(Map<String, String> databaseProperties) {
-    checkState(threadLocalDelegate.get() == null, "activateDatabaseSettings must not be called from a Worker");
-
-    return defaultDelegate.activateDatabaseSettings(databaseProperties);
-  }
-
-  private static final class ServerSettingsImpl extends Settings implements ServerSettings {
-
-    private final Properties rootProperties;
-
-    public ServerSettingsImpl(PropertyDefinitions definitions, Properties rootProperties) {
-      super(definitions);
-      this.rootProperties = rootProperties;
-      super.addProperties(rootProperties);
-      // Secret key is loaded from conf/sonar.properties
-      super.getEncryption().setPathToSecretKey(super.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
-    }
-
-    @Override
-    public ServerSettings activateDatabaseSettings(Map<String, String> databaseProperties) {
-      super.clear();
-
-      // order is important : the last override the first
-      super.addProperties(databaseProperties);
-      super.addProperties(rootProperties);
-
-      return this;
-    }
-
-    @Override
-    public Settings getSettings() {
-      return this;
-    }
-  }
-
-  @Override
-  public Settings getSettings() {
-    return this;
-  }
-
-  @Override
-  public Encryption getEncryption() {
-    return currentSettings().getEncryption();
-  }
-
-  @Override
-  @CheckForNull
-  public String getDefaultValue(String key) {
-    return currentSettings().getDefaultValue(key);
-  }
-
-  @Override
-  public boolean hasKey(String key) {
-    return currentSettings().hasKey(key);
-  }
-
-  @Override
-  public boolean hasDefaultValue(String key) {
-    return currentSettings().hasDefaultValue(key);
-  }
-
-  @Override
-  @CheckForNull
-  public String getString(String key) {
-    return currentDelegate().getString(key);
-  }
-
-  @Override
-  public boolean getBoolean(String key) {
-    return currentSettings().getBoolean(key);
-  }
-
-  @Override
-  public int getInt(String key) {
-    return currentSettings().getInt(key);
-  }
-
-  @Override
-  public long getLong(String key) {
-    return currentSettings().getLong(key);
-  }
-
-  @Override
-  @CheckForNull
-  public Date getDate(String key) {
-    return currentSettings().getDate(key);
-  }
-
-  @Override
-  @CheckForNull
-  public Date getDateTime(String key) {
-    return currentSettings().getDateTime(key);
-  }
-
-  @Override
-  @CheckForNull
-  public Float getFloat(String key) {
-    return currentSettings().getFloat(key);
-  }
-
-  @Override
-  @CheckForNull
-  public Double getDouble(String key) {
-    return currentSettings().getDouble(key);
-  }
-
-  @Override
-  public String[] getStringArray(String key) {
-    return currentSettings().getStringArray(key);
-  }
-
-  @Override
-  public String[] getStringLines(String key) {
-    return currentSettings().getStringLines(key);
-  }
-
-  @Override
-  public String[] getStringArrayBySeparator(String key, String separator) {
-    return currentSettings().getStringArrayBySeparator(key, separator);
-  }
-
-  @Override
-  public List<String> getKeysStartingWith(String prefix) {
-    return currentSettings().getKeysStartingWith(prefix);
-  }
-
-  @Override
-  public Settings appendProperty(String key, String value) {
-    return currentSettings().appendProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable String[] values) {
-    return currentSettings().setProperty(key, values);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable String value) {
-    return currentSettings().setProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Boolean value) {
-    return currentSettings().setProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Integer value) {
-    return currentSettings().setProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Long value) {
-    return currentSettings().setProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Double value) {
-    return currentSettings().setProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Float value) {
-    return currentSettings().setProperty(key, value);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Date date) {
-    return currentSettings().setProperty(key, date);
-  }
-
-  @Override
-  public Settings addProperties(Map<String, String> props) {
-    return currentSettings().addProperties(props);
-  }
-
-  @Override
-  public Settings addProperties(Properties props) {
-    return currentSettings().addProperties(props);
-  }
-
-  @Override
-  public Settings setProperties(Map<String, String> props) {
-    return currentSettings().setProperties(props);
-  }
-
-  @Override
-  public Settings setProperty(String key, @Nullable Date date, boolean includeTime) {
-    return currentSettings().setProperty(key, date, includeTime);
-  }
-
-  @Override
-  public Settings removeProperty(String key) {
-    return currentSettings().removeProperty(key);
-  }
-
-  @Override
-  public Settings clear() {
-    return currentSettings().clear();
-  }
-
-  @Override
-  public Map<String, String> getProperties() {
-    return currentSettings().getProperties();
-  }
-
-  @Override
-  public PropertyDefinitions getDefinitions() {
-    return currentSettings().getDefinitions();
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectSettings.java b/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectSettings.java
new file mode 100644 (file)
index 0000000..02b211e
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.ce.settings;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.config.Settings;
+
+@ComputeEngineSide
+public class ProjectSettings extends Settings {
+
+  private final Map<String, String> projectProps = new HashMap<>();
+  private final Settings globalSettings;
+
+  public ProjectSettings(Settings globalSettings) {
+    super(globalSettings.getDefinitions(), globalSettings.getEncryption());
+    this.globalSettings = globalSettings;
+  }
+
+  @Override
+  protected Optional<String> get(String key) {
+    String value = projectProps.get(key);
+    if (value != null) {
+      return Optional.of(value);
+    }
+    return globalSettings.getRawString(key);
+  }
+
+  @Override
+  protected void set(String key, String value) {
+    projectProps.put(key, value);
+  }
+
+  @Override
+  protected void remove(String key) {
+    projectProps.remove(key);
+  }
+
+  @Override
+  public Map<String, String> getProperties() {
+    // order is important. Project properties override global properties.
+    Map<String, String> result = new HashMap<>();
+    result.putAll(globalSettings.getProperties());
+    result.putAll(projectProps);
+    return result;
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectSettingsFactory.java b/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectSettingsFactory.java
new file mode 100644 (file)
index 0000000..b7ac494
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.ce.settings;
+
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.config.Settings;
+import org.sonar.db.DbClient;
+
+@ComputeEngineSide
+public class ProjectSettingsFactory {
+
+  private final Settings globalSettings;
+  private final DbClient dbClient;
+
+  public ProjectSettingsFactory(Settings globalSettings, DbClient dbClient) {
+    this.globalSettings = globalSettings;
+    this.dbClient = dbClient;
+  }
+
+  public Settings newProjectSettings(String projectKey) {
+    Settings projectSettings = new ProjectSettings(globalSettings);
+    dbClient.propertiesDao()
+      .selectProjectProperties(projectKey)
+      .forEach(property -> projectSettings.setProperty(property.getKey(), property.getValue()));
+    return projectSettings;
+  }
+}
index f1af42124cd03fe84c28c78bd8b4b445cf69969c..7bff35e6baf18f4d265c2b5da2dd10bd1f1288fd 100644 (file)
 package org.sonar.ce.settings;
 
 import org.picocontainer.Startable;
+import org.sonar.api.ce.ComputeEngineSide;
 import org.sonar.server.computation.task.container.EagerStart;
 import org.sonar.server.computation.task.container.TaskContainerImpl;
+import org.sonar.server.setting.ThreadLocalSettings;
 
 /**
  * Add this class as the first components in the {@link TaskContainerImpl}
  * to trigger loading of Thread local specific {@link org.sonar.api.config.Settings} in {@link ThreadLocalSettings}.
  */
 @EagerStart
+@ComputeEngineSide
 public class SettingsLoader implements Startable {
   private final ThreadLocalSettings threadLocalSettings;
 
diff --git a/server/sonar-server/src/main/java/org/sonar/ce/settings/ThreadLocalSettings.java b/server/sonar-server/src/main/java/org/sonar/ce/settings/ThreadLocalSettings.java
deleted file mode 100644 (file)
index 12f5a3d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.ce.settings;
-
-public interface ThreadLocalSettings {
-  /**
-   * Loads up-to-date Settings specific to the current thread.
-   *
-   * @throws IllegalStateException if the current thread already has specific Settings
-   */
-  void load();
-
-  /**
-   * Clears the Settings specific to the current thread (if any).
-   */
-  void unload();
-}
index 189ee6a62026d466725587b521ce02151a355762..1888b74537150d69f8e98fa5b83693e7246c78d4 100644 (file)
 
 package org.sonar.server.authentication;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static io.jsonwebtoken.impl.crypto.MacProvider.generateKey;
-import static java.util.Objects.requireNonNull;
-
+import com.google.common.annotations.VisibleForTesting;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.ExpiredJwtException;
 import io.jsonwebtoken.JwtBuilder;
@@ -45,6 +42,10 @@ import org.sonar.api.utils.System2;
 import org.sonar.core.util.UuidFactory;
 import org.sonar.server.exceptions.UnauthorizedException;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+import static io.jsonwebtoken.impl.crypto.MacProvider.generateKey;
+import static java.util.Objects.requireNonNull;
+
 /**
  * This class can be used to encode or decode a JWT token
  */
@@ -67,13 +68,16 @@ public class JwtSerializer implements Startable {
     this.uuidFactory = uuidFactory;
   }
 
+  @VisibleForTesting
+  SecretKey getSecretKey() {
+    return secretKey;
+  }
+
   @Override
   public void start() {
     String encodedKey = settings.getString(SECRET_KEY_PROPERTY);
     if (encodedKey == null) {
-      SecretKey newSecretKey = generateSecretKey();
-      settings.setProperty(SECRET_KEY_PROPERTY, Base64.getEncoder().encodeToString(newSecretKey.getEncoded()));
-      this.secretKey = newSecretKey;
+      this.secretKey = generateSecretKey();
     } else {
       this.secretKey = decodeSecretKeyProperty(encodedKey);
     }
index 0be0bfcc9eba5b220d8bd66de202748210087b1f..fb7a42fec487ae154236b18edd8b42f8b88886be 100644 (file)
@@ -118,7 +118,7 @@ public class UserSessionInitializer {
   }
 
   public void removeUserSession() {
-    threadLocalSession.remove();
+    threadLocalSession.unload();
   }
 
   // Try first to authenticate from JWT token, then try from basic http header
index 4ca83d404e17836fb29df16b24f534f87816b9b6..4409931eea1d49455480114766e1f3eb69d0812d 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.computation.task.projectanalysis.component;
 import java.util.Collection;
 import java.util.Map;
 import org.sonar.api.config.Settings;
-import org.sonar.server.setting.ProjectSettingsFactory;
+import org.sonar.ce.settings.ProjectSettingsFactory;
 import org.sonar.server.util.cache.CacheLoader;
 import org.sonar.server.util.cache.MemoryCache;
 
index 8668ad9964c275f221aefff81c9443456316a716..f5ccd03bb44e6150a21974ec80d7da791e185de6 100644 (file)
@@ -25,7 +25,6 @@ import javax.annotation.CheckForNull;
 import org.sonar.ce.queue.CeTask;
 import org.sonar.ce.queue.CeTaskResult;
 import org.sonar.ce.settings.SettingsLoader;
-import org.sonar.ce.settings.ThreadLocalSettings;
 import org.sonar.ce.taskprocessor.CeTaskProcessor;
 import org.sonar.core.platform.ComponentContainer;
 import org.sonar.db.ce.CeTaskTypes;
@@ -34,6 +33,7 @@ import org.sonar.server.computation.task.container.TaskContainer;
 import org.sonar.server.computation.task.projectanalysis.container.ContainerFactory;
 import org.sonar.server.computation.task.step.ComputationStepExecutor;
 import org.sonar.server.computation.taskprocessor.TaskResultHolder;
+import org.sonar.server.setting.ThreadLocalSettings;
 
 public class ReportTaskProcessor implements CeTaskProcessor {
 
index fbef6541c27c9dd4547ef506e82f09ad8991d53b..1f5fc214fb2b63e4de988bdada25df7346f30ec2 100644 (file)
  */
 package org.sonar.server.permission.ws.template;
 
-import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty;
-import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser;
-import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
-import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
-import static org.sonar.server.permission.ws.WsTemplateRef.newTemplateRef;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
-import static org.sonar.server.ws.WsParameterBuilder.createRootQualifierParameter;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
-
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceTypes;
@@ -45,6 +34,17 @@ import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.client.permission.SetDefaultTemplateWsRequest;
 
+import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty;
+import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser;
+import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
+import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
+import static org.sonar.server.permission.ws.WsTemplateRef.newTemplateRef;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
+import static org.sonar.server.ws.WsParameterBuilder.createRootQualifierParameter;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
+
 public class SetDefaultTemplateAction implements PermissionsWsAction {
   private final DbClient dbClient;
   private final PermissionDependenciesFinder finder;
index 852970b97390eab1744edd8356d1534f625d6bdf..454a8c11fcb1a6121fc7b71befa51710e10fd5b2 100644 (file)
  */
 package org.sonar.server.platform;
 
-import com.google.common.collect.Maps;
-import java.util.List;
-import java.util.Map;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import org.picocontainer.Startable;
 import org.sonar.api.config.Settings;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.property.PropertiesDao;
 import org.sonar.db.property.PropertyDto;
 
-/**
- * @since 3.2
- */
-public class PersistentSettings implements Startable {
+public class PersistentSettings {
+
+  private final Settings delegate;
   private final DbClient dbClient;
-  private final PropertiesDao propertiesDao;
-  private final ServerSettings serverSettings;
+  private final SettingsChangeNotifier changeNotifier;
 
-  public PersistentSettings(DbClient dbClient, ServerSettings serverSettings) {
+  public PersistentSettings(Settings delegate, DbClient dbClient, SettingsChangeNotifier changeNotifier) {
+    this.delegate = delegate;
     this.dbClient = dbClient;
-    this.propertiesDao = dbClient.propertiesDao();
-    this.serverSettings = serverSettings;
+    this.changeNotifier = changeNotifier;
   }
 
-  @Override
-  public void start() {
-    Map<String, String> databaseProperties = Maps.newHashMap();
-    for (PropertyDto property : getGlobalProperties()) {
-      databaseProperties.put(property.getKey(), property.getValue());
-    }
-    serverSettings.activateDatabaseSettings(databaseProperties);
+  @CheckForNull
+  public String getString(String key) {
+    return delegate.getString(key);
   }
 
-  @Override
-  public void stop() {
-    // nothing to do
+  /**
+   * Insert property into database if value is not {@code null}, else delete property from
+   * database. Session is not committed but {@link org.sonar.api.config.GlobalPropertyChangeHandler}
+   * are executed.
+   */
+  public PersistentSettings saveProperty(DbSession dbSession, String key, @Nullable String value) {
+    if (value == null) {
+      dbClient.propertiesDao().deleteGlobalProperty(key, dbSession);
+    } else {
+      dbClient.propertiesDao().insertProperty(dbSession, new PropertyDto().setKey(key).setValue(value));
+    }
+    // refresh the cache of settings
+    delegate.setProperty(key, value);
+
+    changeNotifier.onGlobalPropertyChange(key, value);
+    return this;
   }
 
+  /**
+   * Same as {@link #saveProperty(DbSession, String, String)} but a new database session is
+   * opened and committed.
+   */
   public PersistentSettings saveProperty(String key, @Nullable String value) {
-    DbSession dbSession = dbClient.openSession(false);
-    try {
+    try (DbSession dbSession = dbClient.openSession(false)) {
       saveProperty(dbSession, key, value);
       dbSession.commit();
-    } finally {
-      dbClient.closeSession(dbSession);
+      return this;
     }
-    return this;
-  }
-
-  public PersistentSettings saveProperty(DbSession dbSession, String key, @Nullable String value) {
-    serverSettings.setProperty(key, value);
-    propertiesDao.insertProperty(dbSession, new PropertyDto().setKey(key).setValue(value));
-    return this;
-  }
-
-  public PersistentSettings deleteProperty(String key) {
-    serverSettings.removeProperty(key);
-    propertiesDao.deleteGlobalProperty(key);
-    return this;
-  }
-
-  public PersistentSettings deleteProperties() {
-    serverSettings.clear();
-    propertiesDao.deleteGlobalProperties();
-    return this;
-  }
-
-  public PersistentSettings saveProperties(Map<String, String> properties) {
-    serverSettings.addProperties(properties);
-    propertiesDao.insertGlobalProperties(properties);
-    return this;
-  }
-
-  public String getString(String key) {
-    return serverSettings.getString(key);
-  }
-
-  public Map<String, String> getProperties() {
-    return serverSettings.getProperties();
   }
 
   public Settings getSettings() {
-    return serverSettings.getSettings();
-  }
-
-  public List<PropertyDto> getGlobalProperties() {
-    return propertiesDao.selectGlobalProperties();
+    return delegate;
   }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java
deleted file mode 100644 (file)
index 8b03af4..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.platform;
-
-import java.util.Map;
-import javax.annotation.Nullable;
-import org.sonar.api.config.Settings;
-
-/**
- * Defines some of the methods of {@link Settings} plus some specific to load db properties on the server side
- * (see {@link PersistentSettings}).
- */
-public interface ServerSettings {
-  ServerSettings activateDatabaseSettings(Map<String, String> databaseProperties);
-
-  Settings getSettings();
-
-  /**
-   * @see Settings#getString(String)
-   */
-  String getString(String key);
-
-  /**
-   * @see Settings#getProperties()
-   */
-  Map<String, String> getProperties();
-
-  /**
-   * @see Settings#hasKey(String)
-   */
-  boolean hasKey(String foo);
-
-  /**
-   * @see Settings#setProperty(String, String)
-   */
-  Settings setProperty(String key, @Nullable String value);
-
-  /**
-   * @see Settings#removeProperty(String)
-   */
-  Settings removeProperty(String key);
-
-  /**
-   * @see Settings#clear()
-   */
-  Settings clear();
-
-  /**
-   * @see Settings#addProperties(Map)
-   */
-  Settings addProperties(Map<String, String> properties);
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerSettingsImpl.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerSettingsImpl.java
deleted file mode 100644 (file)
index f7ddfbc..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.platform;
-
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.Settings;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Load settings in the following order (the last override the first) :
- * <ol>
- * <li>general settings persisted in database</li>
- * <li>file $SONAR_HOME/conf/sonar.properties</li>
- * <li>environment variables</li>
- * <li>system properties</li>
- * </ol>
- */
-public class ServerSettingsImpl extends Settings implements ServerSettings {
-
-  private final Properties bootstrapProperties;
-
-  public ServerSettingsImpl(PropertyDefinitions definitions, Properties bootstrapProperties) {
-    super(definitions);
-    this.bootstrapProperties = bootstrapProperties;
-    load(Collections.emptyMap());
-    // Secret key is loaded from conf/sonar.properties
-    getEncryption().setPathToSecretKey(getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
-  }
-
-  @Override
-  public ServerSettings activateDatabaseSettings(Map<String, String> databaseProperties) {
-    return load(databaseProperties);
-  }
-
-  @Override
-  public Settings getSettings() {
-    return this;
-  }
-
-  private ServerSettings load(Map<String, String> databaseSettings) {
-    clear();
-
-    // order is important : the last override the first
-    addProperties(databaseSettings);
-    addProperties(bootstrapProperties);
-
-    return this;
-  }
-}
index f06936662dbf25210847cb3e165d1a45a26af764..10a63b2fd696d6ab84cd1f09167cc862d7321836 100644 (file)
  */
 package org.sonar.server.platform;
 
-import com.google.common.collect.ImmutableMap;
 import java.util.Date;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.Startable;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.db.DbClient;
+import org.sonar.db.property.PropertyDto;
 
 /**
  * The server node marked as "startup leader" generates some information about startup. These
@@ -37,19 +37,25 @@ import org.sonar.db.DbClient;
 public class StartupMetadataPersister implements Startable {
 
   private final StartupMetadata metadata;
-  private final PersistentSettings persistentSettings;
+  // PersistentSettings can not be used as it has to be
+  // instantiated in level 4 of container, whereas
+  // StartupMetadataPersister is level 3.
+  private final DbClient dbClient;
 
-  public StartupMetadataPersister(StartupMetadata metadata, PersistentSettings persistentSettings) {
+  public StartupMetadataPersister(StartupMetadata metadata, DbClient dbClient) {
     this.metadata = metadata;
-    this.persistentSettings = persistentSettings;
+    this.dbClient = dbClient;
   }
 
   @Override
   public void start() {
     String startedAt = DateUtils.formatDateTime(new Date(metadata.getStartedAt()));
-    persistentSettings.saveProperties(ImmutableMap.of(
-      CoreProperties.SERVER_ID, metadata.getStartupId(),
-      CoreProperties.SERVER_STARTTIME, startedAt));
+    save(CoreProperties.SERVER_ID, metadata.getStartupId());
+    save(CoreProperties.SERVER_STARTTIME, startedAt);
+  }
+
+  private void save(String key, String value) {
+    dbClient.propertiesDao().insertProperty(new PropertyDto().setKey(key).setValue(value));
   }
 
   @Override
index 9ba970debd0e4af8ea4b15bab7ebf8fc342ac2eb..e6568ad02d86f1fcefeb943438e50f4c4cf8b7a0 100644 (file)
@@ -45,7 +45,6 @@ import org.sonar.server.platform.DatabaseServerCompatibility;
 import org.sonar.server.platform.LogServerVersion;
 import org.sonar.server.platform.Platform;
 import org.sonar.server.platform.ServerFileSystemImpl;
-import org.sonar.server.platform.ServerSettingsImpl;
 import org.sonar.server.platform.TempFolderProvider;
 import org.sonar.server.platform.UrlSettings;
 import org.sonar.server.platform.cluster.ClusterImpl;
@@ -55,6 +54,7 @@ import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
 import org.sonar.server.ruby.PlatformRackBridge;
 import org.sonar.server.rule.index.RuleIndex;
 import org.sonar.server.search.EsSearchModule;
+import org.sonar.server.setting.ThreadLocalSettings;
 import org.sonar.server.user.ThreadLocalUserSession;
 
 public class PlatformLevel1 extends PlatformLevel {
@@ -78,10 +78,10 @@ public class PlatformLevel1 extends PlatformLevel {
     add(
       new SonarQubeVersion(apiVersion),
       SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SERVER),
+      ThreadLocalSettings.class,
       LogServerVersion.class,
       ProcessCommandWrapperImpl.class,
       RestartFlagHolderImpl.class,
-      ServerSettingsImpl.class,
       DefaultHttpDownloader.class,
       UuidFactoryImpl.INSTANCE,
       UrlSettings.class,
index eda34af591fd13817f48a94bb59b2278111ee6d3..e93c580fdf2a7f3b3adc133343fb500174775b2f 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.platform.platformlevel;
 
-import org.sonar.api.utils.Durations;
 import org.sonar.core.i18n.DefaultI18n;
 import org.sonar.core.i18n.RuleI18nManager;
 import org.sonar.core.platform.PluginClassloaderFactory;
@@ -39,7 +38,6 @@ import org.sonar.server.plugins.ServerPluginJarExploder;
 import org.sonar.server.plugins.ServerPluginRepository;
 import org.sonar.server.plugins.WebServerExtensionInstaller;
 import org.sonar.server.ruby.PlatformRubyBridge;
-import org.sonar.server.ui.JRubyI18n;
 
 public class PlatformLevel2 extends PlatformLevel {
   public PlatformLevel2(PlatformLevel parent) {
@@ -66,11 +64,10 @@ public class PlatformLevel2 extends PlatformLevel {
 
       // depends on plugins
       RailsAppsDeployer.class,
-      JRubyI18n.class,
       DefaultI18n.class,
       RuleI18nManager.class,
-      Durations.class,
 
+      
       // DB migration
       PlatformDatabaseMigrationExecutorServiceImpl.class,
       PlatformDatabaseMigration.class,
index d221eadc8e00c649426c15cbcdb85ef0f04af09e..30ddf76a312118d9e566e965459d2f8caa0f4ffd 100644 (file)
  */
 package org.sonar.server.platform.platformlevel;
 
+import org.sonar.api.utils.Durations;
 import org.sonar.api.utils.UriReader;
-import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.platform.ServerIdGenerator;
 import org.sonar.server.platform.ServerIdLoader;
 import org.sonar.server.platform.StartupMetadataPersister;
+import org.sonar.server.setting.DatabaseSettingLoader;
+import org.sonar.server.setting.DatabaseSettingsEnabler;
 import org.sonar.server.startup.LogServerId;
+import org.sonar.server.ui.JRubyI18n;
 
 public class PlatformLevel3 extends PlatformLevel {
   public PlatformLevel3(PlatformLevel parent) {
@@ -35,7 +38,10 @@ public class PlatformLevel3 extends PlatformLevel {
   protected void configureLevel() {
     addIfStartupLeader(StartupMetadataPersister.class);
     add(
-      PersistentSettings.class,
+      DatabaseSettingLoader.class,
+      DatabaseSettingsEnabler.class,
+      Durations.class,
+      JRubyI18n.class,
       UriReader.class,
       ServerIdLoader.class,
       ServerIdGenerator.class,
index 6070b48943658bd7196d7fc93551b3c2f7240b27..6b46550503102c0c916f7b78b35994d27ec7c50c 100644 (file)
@@ -30,6 +30,7 @@ import org.sonar.api.rules.AnnotationRuleParser;
 import org.sonar.api.rules.XMLRuleParser;
 import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
 import org.sonar.ce.CeModule;
+import org.sonar.ce.settings.ProjectSettingsFactory;
 import org.sonar.core.component.DefaultResourceTypes;
 import org.sonar.core.timemachine.Periods;
 import org.sonar.db.permission.PermissionRepository;
@@ -141,6 +142,7 @@ import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.permission.ws.PermissionsWsModule;
 import org.sonar.server.platform.BackendCleanup;
+import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.platform.ServerLogging;
 import org.sonar.server.platform.SettingsChangeNotifier;
 import org.sonar.server.platform.monitoring.DatabaseMonitor;
@@ -237,7 +239,6 @@ import org.sonar.server.rule.ws.RuleQueryFactory;
 import org.sonar.server.rule.ws.RulesWs;
 import org.sonar.server.rule.ws.TagsAction;
 import org.sonar.server.serverid.ws.ServerIdWsModule;
-import org.sonar.server.setting.ProjectSettingsFactory;
 import org.sonar.server.setting.ws.SettingsWsModule;
 import org.sonar.server.source.HtmlSourceDecorator;
 import org.sonar.server.source.SourceService;
@@ -454,6 +455,7 @@ public class PlatformLevel4 extends PlatformLevel {
       WebServiceFilter.class,
 
       // localization
+
       L10nWs.class,
 
       // authentication
@@ -586,6 +588,7 @@ public class PlatformLevel4 extends PlatformLevel {
       TestIndexer.class,
 
       // Settings
+      PersistentSettings.class,
       PropertiesWs.class,
       SettingsWsModule.class,
 
index 08bcbc4897a50af72b320eca7c24e2b0914f7a82..aa49cd36df39faba39db965d013abb24017865bf 100644 (file)
@@ -29,7 +29,6 @@ import javax.annotation.Nullable;
 import org.apache.commons.lang.BooleanUtils;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
-import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.Metric.ValueType;
@@ -72,9 +71,8 @@ public class QualityGates {
   private final PropertiesDao propertiesDao;
   private final ComponentDao componentDao;
   private final UserSession userSession;
-  private final Settings settings;
 
-  public QualityGates(DbClient dbClient, MetricFinder metricFinder, UserSession userSession, Settings settings) {
+  public QualityGates(DbClient dbClient, MetricFinder metricFinder, UserSession userSession) {
     this.dbClient = dbClient;
     this.dao = dbClient.qualityGateDao();
     this.conditionDao = dbClient.gateConditionDao();
@@ -82,7 +80,6 @@ public class QualityGates {
     this.propertiesDao = dbClient.propertiesDao();
     this.componentDao = dbClient.componentDao();
     this.userSession = userSession;
-    this.settings = settings;
   }
 
   public QualityGateDto create(String name) {
@@ -155,11 +152,9 @@ public class QualityGates {
     checkPermission();
     if (idToUseAsDefault == null) {
       propertiesDao.deleteGlobalProperty(SONAR_QUALITYGATE_PROPERTY);
-      settings.removeProperty(SONAR_QUALITYGATE_PROPERTY);
     } else {
       QualityGateDto newDefault = getNonNullQgate(idToUseAsDefault);
       propertiesDao.insertProperty(new PropertyDto().setKey(SONAR_QUALITYGATE_PROPERTY).setValue(newDefault.getId().toString()));
-      settings.setProperty(SONAR_QUALITYGATE_PROPERTY, idToUseAsDefault);
     }
   }
 
diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/DatabaseSettingLoader.java b/server/sonar-server/src/main/java/org/sonar/server/setting/DatabaseSettingLoader.java
new file mode 100644 (file)
index 0000000..b9a8f36
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.collect.ImmutableMap;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.property.PropertyDto;
+
+import static org.apache.commons.lang.StringUtils.defaultString;
+
+public class DatabaseSettingLoader implements SettingLoader {
+
+  private final DbClient dbClient;
+
+  public DatabaseSettingLoader(DbClient dbClient) {
+    this.dbClient = dbClient;
+  }
+
+  @Override
+  public String load(String key) {
+    PropertyDto dto = dbClient.propertiesDao().selectGlobalProperty(key);
+    if (dto != null) {
+      return defaultString(dto.getValue());
+    }
+    return null;
+  }
+
+  @Override
+  public void loadAll(ImmutableMap.Builder<String, String> appendTo) {
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      dbClient.propertiesDao().selectGlobalProperties(dbSession)
+        .forEach(p -> appendTo.put(p.getKey(), defaultString(p.getValue())));
+    }
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/DatabaseSettingsEnabler.java b/server/sonar-server/src/main/java/org/sonar/server/setting/DatabaseSettingsEnabler.java
new file mode 100644 (file)
index 0000000..992fff4
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import org.sonar.api.Startable;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.server.ServerSide;
+
+@ComputeEngineSide
+@ServerSide
+public class DatabaseSettingsEnabler implements Startable {
+
+  private final ThreadLocalSettings settings;
+  private final DatabaseSettingLoader loader;
+
+  public DatabaseSettingsEnabler(ThreadLocalSettings settings, DatabaseSettingLoader loader) {
+    this.settings = settings;
+    this.loader = loader;
+  }
+
+  @Override
+  public void start() {
+    settings.setSettingLoader(loader);
+  }
+
+  @Override
+  public void stop() {
+    // nothing to do
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/NopSettingLoader.java b/server/sonar-server/src/main/java/org/sonar/server/setting/NopSettingLoader.java
new file mode 100644 (file)
index 0000000..88d6e67
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.collect.ImmutableMap;
+
+public class NopSettingLoader implements SettingLoader {
+  @Override
+  public String load(String key) {
+    return null;
+  }
+
+  @Override
+  public void loadAll(ImmutableMap.Builder<String, String> appendTo) {
+    // nothing to load
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ProjectSettingsFactory.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ProjectSettingsFactory.java
deleted file mode 100644 (file)
index b1667da..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.setting;
-
-import java.util.List;
-import org.sonar.api.ce.ComputeEngineSide;
-import org.sonar.api.config.Settings;
-import org.sonar.api.server.ServerSide;
-import org.sonar.db.property.PropertiesDao;
-import org.sonar.db.property.PropertyDto;
-
-@ServerSide
-@ComputeEngineSide
-public class ProjectSettingsFactory {
-
-  private final PropertiesDao dao;
-  private final Settings settings;
-
-  public ProjectSettingsFactory(Settings settings, PropertiesDao dao) {
-    this.dao = dao;
-    this.settings = settings;
-  }
-
-  public Settings newProjectSettings(String projectKey) {
-    List<PropertyDto> propertyList = dao.selectProjectProperties(projectKey);
-    Settings projectSettings = new Settings(settings);
-    for (PropertyDto property : propertyList) {
-      projectSettings.setProperty(property.getKey(), property.getValue());
-    }
-    return projectSettings;
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/SettingLoader.java b/server/sonar-server/src/main/java/org/sonar/server/setting/SettingLoader.java
new file mode 100644 (file)
index 0000000..f17b3b2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.collect.ImmutableMap;
+import javax.annotation.CheckForNull;
+
+public interface SettingLoader {
+
+  @CheckForNull
+  String load(String key);
+
+  void loadAll(ImmutableMap.Builder<String, String> appendTo);
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java b/server/sonar-server/src/main/java/org/sonar/server/setting/ThreadLocalSettings.java
new file mode 100644 (file)
index 0000000..4167d8d
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.config.Encryption;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.Settings;
+import org.sonar.api.server.ServerSide;
+
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * Merge of {@link SystemSettings} and the global properties stored in the db table "properties". These
+ * settings do not contain the settings specific to a project.
+ *
+ * <p>
+ * System settings have precedence on others.
+ * </p>
+ *
+ * <p>
+ * The thread-local cache is optional. It is disabled when the method {@link #unload()} has not
+ * been called. That allows to remove complexity with handling of cleanup of thread-local cache
+ * on daemon threads (notifications) or startup "main" thread.
+ * </p>
+ */
+@ComputeEngineSide
+@ServerSide
+public class ThreadLocalSettings extends Settings {
+
+  private final Properties systemProps;
+  private static final ThreadLocal<Map<String, String>> CACHE = new ThreadLocal<>();
+  private SettingLoader settingLoader;
+
+  public ThreadLocalSettings(PropertyDefinitions definitions, Properties props) {
+    this(definitions, props, new NopSettingLoader());
+  }
+
+  @VisibleForTesting
+  ThreadLocalSettings(PropertyDefinitions definitions, Properties props, SettingLoader settingLoader) {
+    super(definitions, new Encryption(null));
+    this.settingLoader = settingLoader;
+    this.systemProps = props;
+
+    // TODO something wrong about lifecycle here. It could be improved
+    getEncryption().setPathToSecretKey(props.getProperty(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
+  }
+
+  @VisibleForTesting
+  SettingLoader getSettingLoader() {
+    return settingLoader;
+  }
+
+  protected void setSettingLoader(SettingLoader settingLoader) {
+    this.settingLoader = Objects.requireNonNull(settingLoader);
+  }
+
+  @Override
+  protected Optional<String> get(String key) {
+    // search for the first value available in
+    // 1. system properties
+    // 2. thread local cache (if enabled)
+    // 3. db
+
+    String value = systemProps.getProperty(key);
+    if (value != null) {
+      return Optional.of(value);
+    }
+
+    Map<String, String> dbProps = CACHE.get();
+    // caching is disabled
+    if (dbProps == null) {
+      return Optional.ofNullable(settingLoader.load(key));
+    }
+
+    String loadedValue;
+    if (dbProps.containsKey(key)) {
+      // property may not exist in db. In this case key is present
+      // in cache but value is null
+      loadedValue = dbProps.get(key);
+    } else {
+      // cache the effective value (null if the property
+      // is not persisted)
+      loadedValue = settingLoader.load(key);
+      dbProps.put(key, loadedValue);
+    }
+    return Optional.ofNullable(loadedValue);
+  }
+
+  @Override
+  protected void set(String key, String value) {
+    Map<String, String> dbProps = CACHE.get();
+    if (dbProps != null) {
+      dbProps.put(key, value);
+    }
+  }
+
+  @Override
+  protected void remove(String key) {
+    Map<String, String> dbProps = CACHE.get();
+    if (dbProps != null) {
+      dbProps.remove(key);
+    }
+  }
+
+  /**
+   * Enables the thread specific cache of settings.
+   *
+   * @throws IllegalStateException if the current thread already has specific cache
+   */
+  public void load() {
+    checkState(CACHE.get() == null,
+      "load called twice for thread '%s' or state wasn't cleared last time it was used", Thread.currentThread().getName());
+    CACHE.set(new HashMap<>());
+  }
+
+  /**
+   * Clears the cache specific to the current thread (if any).
+   */
+  public void unload() {
+    CACHE.remove();
+  }
+
+  @Override
+  public Map<String, String> getProperties() {
+    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+    settingLoader.loadAll(builder);
+    systemProps.entrySet().forEach(entry -> builder.put((String) entry.getKey(), (String) entry.getValue()));
+    return builder.build();
+  }
+}
index 1db6e6091bfe2606647d3a8f1c12c4131889efdb..0789b460c1ffbaf52e6554ed6b09887c815684ba 100644 (file)
@@ -53,15 +53,14 @@ import org.sonar.db.version.DatabaseVersion;
 import org.sonar.process.ProcessProperties;
 import org.sonar.server.authentication.IdentityProviderRepository;
 import org.sonar.server.component.ComponentCleanerService;
-import org.sonar.server.platform.db.migrations.DatabaseMigrator;
 import org.sonar.server.measure.MeasureFilterEngine;
 import org.sonar.server.measure.MeasureFilterResult;
 import org.sonar.server.platform.Platform;
 import org.sonar.server.platform.ServerIdGenerator;
-import org.sonar.server.platform.ServerSettings;
-import org.sonar.server.platform.SettingsChangeNotifier;
+import org.sonar.server.platform.db.migrations.DatabaseMigrator;
 import org.sonar.server.platform.ws.UpgradesAction;
 import org.sonar.server.rule.RuleRepositories;
+import org.sonar.server.platform.PersistentSettings;
 import org.sonar.server.user.NewUserNotifier;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -191,8 +190,7 @@ public final class JRubyFacade {
   }
 
   public void setGlobalProperty(String key, @Nullable String value) {
-    get(ServerSettings.class).setProperty(key, value);
-    get(SettingsChangeNotifier.class).onGlobalPropertyChange(key, value);
+    get(PersistentSettings.class).saveProperty(key, value);
   }
 
   public Settings getSettings() {
index 846878961783abcdb63dd2a7635b0d2214391a14..5d7d742a71c6167b76c6f04ec9b448f2dfd9e964 100644 (file)
@@ -97,7 +97,7 @@ public final class DoPrivileged {
     }
   
     private void stop() {
-      threadLocalUserSession.remove();
+      threadLocalUserSession.unload();
       if (oldUserSession != null) {
         threadLocalUserSession.set(oldUserSession);
       }
index b13fcb51753cdd906b16f93d871136b5b3ccc584..a1363e103d6b8203c65792a341b473a783f591b7 100644 (file)
@@ -23,10 +23,10 @@ import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.picocontainer.Startable;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.server.ServerSide;
 import org.sonar.api.config.Settings;
 import org.sonar.api.security.LoginPasswordAuthenticator;
 import org.sonar.api.security.SecurityRealm;
+import org.sonar.api.server.ServerSide;
 import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
index 9ec8f3c34ba47cc7bcf3d93873e038a9e573828e..94d1a99792681e4ae2aa4bfa0cf1f6ecb2451f08 100644 (file)
@@ -31,26 +31,26 @@ import org.sonar.server.exceptions.UnauthorizedException;
  */
 public class ThreadLocalUserSession implements UserSession {
 
-  private static final ThreadLocal<UserSession> THREAD_LOCAL = new ThreadLocal<>();
+  private static final ThreadLocal<UserSession> DELEGATE = new ThreadLocal<>();
 
   public UserSession get() {
-    UserSession currentUserSession = THREAD_LOCAL.get();
-    if (currentUserSession != null) {
-      return currentUserSession;
+    UserSession session = DELEGATE.get();
+    if (session != null) {
+      return session;
     }
     throw new UnauthorizedException();
   }
 
   public void set(UserSession session) {
-    THREAD_LOCAL.set(session);
+    DELEGATE.set(session);
   }
 
-  public void remove() {
-    THREAD_LOCAL.remove();
+  public void unload() {
+    DELEGATE.remove();
   }
 
   public boolean hasSession() {
-    return THREAD_LOCAL.get() != null;
+    return DELEGATE.get() != null;
   }
 
   @Override
index 58c351e6ea2da5a08373e8665fbed17405e64252..535641746e9854f819b6369782f50ba0e19c3ed5 100644 (file)
@@ -31,11 +31,11 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.sonar.server.authentication.UserSessionInitializer;
 import org.sonar.server.platform.Platform;
+import org.sonar.server.setting.ThreadLocalSettings;
 
 public class UserSessionFilter implements Filter {
 
   private final Platform platform;
-  private UserSessionInitializer userSessionInitializer;
 
   public UserSessionFilter() {
     this.platform = Platform.getInstance();
@@ -48,27 +48,22 @@ public class UserSessionFilter implements Filter {
 
   @Override
   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
+    HttpServletRequest request = (HttpServletRequest) servletRequest;
+    HttpServletResponse response = (HttpServletResponse) servletResponse;
+
+    ThreadLocalSettings settings = platform.getContainer().getComponentByType(ThreadLocalSettings.class);
+    UserSessionInitializer userSessionInitializer = platform.getContainer().getComponentByType(UserSessionInitializer.class);
+
+    settings.load();
     try {
-      HttpServletRequest request = (HttpServletRequest) servletRequest;
-      HttpServletResponse response = (HttpServletResponse) servletResponse;
-      init();
-      if (!isInitialized() || userSessionInitializer.initUserSession(request, response)) {
+      if (userSessionInitializer == null || userSessionInitializer.initUserSession(request, response)) {
         chain.doFilter(servletRequest, servletResponse);
       }
     } finally {
-      if (isInitialized()) {
+      if (userSessionInitializer != null) {
         userSessionInitializer.removeUserSession();
       }
-    }
-  }
-
-  private boolean isInitialized() {
-    return userSessionInitializer != null;
-  }
-
-  private void init() {
-    if (userSessionInitializer == null) {
-      userSessionInitializer = platform.getContainer().getComponentByType(UserSessionInitializer.class);
+      settings.unload();
     }
   }
 
index 64cdd6c5f5b202525030bd9d41f303e76664064c..431bcc00b903abaf1e5af07dd1ecc33854418374 100644 (file)
@@ -30,6 +30,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.process.DefaultProcessCommands;
@@ -55,7 +56,7 @@ public class CeHttpClientTest {
   @Before
   public void setUp() throws Exception {
     ipcSharedDir = temp.newFolder();
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(ProcessEntryPoint.PROPERTY_SHARED_PATH, ipcSharedDir.getAbsolutePath());
     underTest = new CeHttpClient(settings);
   }
diff --git a/server/sonar-server/src/test/java/org/sonar/ce/settings/ComputeEngineSettingsTest.java b/server/sonar-server/src/test/java/org/sonar/ce/settings/ComputeEngineSettingsTest.java
deleted file mode 100644 (file)
index c7e2665..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.ce.settings;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Encryption;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.db.DbClient;
-import org.sonar.db.property.PropertiesDao;
-import org.sonar.db.property.PropertyDto;
-
-import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ComputeEngineSettingsTest {
-  private static final String PROPERTY_KEY_1 = "property key 1";
-  private static final String PROPERTY_VALUE_1 = "property value 1";
-  private static final String PROPERTY_KEY_2 = "property key 2";
-  private static final String PROPERTY_VALUE_2 = "property value 2";
-  private static final String OTHER_PROP_1 = "otherProp1";
-  private static final String OTHER_PROP_1_VALUE = "otherProp1Value";
-  private static final String OTHER_PROP_2 = "otherProp2";
-  private static final String OTHER_PROP_2_VALUE = "otherProp2Value";
-  private static final String PROPERTY_3 = "property 3";
-  private static final String PROPERTY_VALUE_3 = "property value 3";
-  private static final String THREAD_PROPERTY = "thread";
-  private static final String MAIN = "main";
-  private static final String CAPTOR = "captor";
-
-  @Rule
-  public ExpectedException expectedException = ExpectedException.none();
-
-  private PropertyDefinitions propertyDefinitions = new PropertyDefinitions();
-  private Properties rootProperties = new Properties();
-  private ComponentContainer container = new ComponentContainer();
-  private DbClient dbClient = mock(DbClient.class);
-  private PropertiesDao propertiesDao = mock(PropertiesDao.class);
-  private ComputeEngineSettings underTest = new ComputeEngineSettings(propertyDefinitions, rootProperties, container);
-
-  @Before
-  public void setUp() throws Exception {
-    rootProperties.setProperty(PROPERTY_KEY_1, PROPERTY_VALUE_1);
-    rootProperties.setProperty(PROPERTY_KEY_2, PROPERTY_VALUE_2);
-    container.add(dbClient);
-    when(dbClient.propertiesDao()).thenReturn(propertiesDao);
-    when(propertiesDao.selectGlobalProperties()).thenReturn(ImmutableList.of(
-      new PropertyDto().setKey(PROPERTY_KEY_1).setValue(PROPERTY_VALUE_1),
-      new PropertyDto().setKey(PROPERTY_KEY_2).setValue(PROPERTY_VALUE_2)));
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    // prevent ThreadLocal leak
-    underTest.unload();
-  }
-
-  @Test
-  public void activateDatabaseSettings_populates_default_settings_with_content_of_root_properties_plus_map_argument_content() {
-    assertThat(underTest.getProperties()).isEmpty();
-
-    ImmutableMap<String, String> properties = ImmutableMap.of(OTHER_PROP_1, OTHER_PROP_1_VALUE, OTHER_PROP_2, OTHER_PROP_2_VALUE);
-    underTest.activateDatabaseSettings(properties);
-
-    assertThat(underTest.getProperties()).containsOnly(
-      entry(PROPERTY_KEY_1, PROPERTY_VALUE_1),
-      entry(PROPERTY_KEY_2, PROPERTY_VALUE_2),
-      entry(OTHER_PROP_1, OTHER_PROP_1_VALUE),
-      entry(OTHER_PROP_2, OTHER_PROP_2_VALUE));
-
-  }
-
-  @Test
-  public void load_creates_a_thread_specific_properties_map() throws InterruptedException {
-    Map<String, String> defaultProperties = underTest.getProperties();
-    assertThat(defaultProperties).isEmpty();
-
-    rootProperties.setProperty(THREAD_PROPERTY, MAIN);
-    underTest.load();
-
-    assertThat(underTest.getProperties()).contains(entry(THREAD_PROPERTY, MAIN));
-
-    PropertiesCaptorThread loadPropertiesCaptor = new PropertiesCaptorThread(true);
-
-    loadPropertiesCaptor.blockingExecute();
-    assertThat(loadPropertiesCaptor.properties).contains(entry(THREAD_PROPERTY, CAPTOR));
-
-    PropertiesCaptorThread noLoadPropertiesCaptor = new PropertiesCaptorThread(false);
-
-    noLoadPropertiesCaptor.blockingExecute();
-    assertThat(noLoadPropertiesCaptor.properties).isEmpty();
-
-    underTest.unload();
-
-    assertThat(underTest.getProperties()).isEmpty();
-  }
-
-  @Test
-  public void load_throws_ISE_if_load_called_twice_without_unload_in_between() {
-    underTest.load();
-
-    expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage("loadLocal called twice for Thread '" + Thread.currentThread().getName()
-      + "' or state wasn't cleared last time it was used");
-
-    underTest.load();
-  }
-
-  @Test
-  public void getEncryption_returns_object_specific_to_current_thread_after_load() throws InterruptedException {
-    Encryption defaultEncryption = underTest.getEncryption();
-
-    underTest.load();
-
-    Encryption mainEncryption = underTest.getEncryption();
-    assertThat(mainEncryption).isNotSameAs(defaultEncryption);
-
-    EncryptionCaptorThread loadEncryptionCaptor = new EncryptionCaptorThread(true);
-    loadEncryptionCaptor.blockingExecute();
-
-    assertThat(loadEncryptionCaptor.encryption).isNotSameAs(defaultEncryption);
-    assertThat(loadEncryptionCaptor.encryption).isNotSameAs(mainEncryption);
-
-    EncryptionCaptorThread noLoadEncryptionCaptor = new EncryptionCaptorThread(false);
-    noLoadEncryptionCaptor.blockingExecute();
-
-    assertThat(noLoadEncryptionCaptor.encryption).isSameAs(defaultEncryption);
-
-    underTest.unload();
-
-    assertThat(underTest.getEncryption()).isSameAs(defaultEncryption);
-  }
-
-  @Test
-  public void getSettings_always_returns_current_ComputeEngineSettings_object() {
-    assertThat(underTest.getSettings()).isSameAs(underTest);
-
-    underTest.load();
-
-    assertThat(underTest.getSettings()).isSameAs(underTest);
-
-    underTest.unload();
-
-    assertThat(underTest.getSettings()).isSameAs(underTest);
-  }
-
-  @Test
-  public void clear_clears_settings_specific_to_current_thread_if_any() {
-    underTest.activateDatabaseSettings(Collections.<String, String>emptyMap());
-    assertThat(underTest.getProperties()).isNotEmpty();
-
-    underTest.load();
-
-    assertThat(underTest.getProperties()).isNotEmpty();
-
-    underTest.clear();
-
-    assertThat(underTest.getProperties()).isEmpty();
-
-    underTest.unload();
-
-    assertThat(underTest.getProperties()).isNotEmpty();
-
-    underTest.clear();
-
-    assertThat(underTest.getProperties()).isEmpty();
-  }
-
-  @Test
-  public void removeProperty_removes_property_in_settings_specific_to_current_thread_if_any() {
-    underTest.activateDatabaseSettings(Collections.<String, String>emptyMap());
-    assertThat(underTest.getProperties()).containsKey(PROPERTY_KEY_2);
-
-    underTest.load();
-
-    assertThat(underTest.getProperties()).containsKey(PROPERTY_KEY_2);
-
-    underTest.removeProperty(PROPERTY_KEY_2);
-
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_KEY_2);
-
-    underTest.unload();
-
-    assertThat(underTest.getProperties()).containsKey(PROPERTY_KEY_2);
-
-    underTest.clear();
-
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_KEY_2);
-  }
-
-  @Test
-  public void setProperty_sets_property_in_settings_specific_to_current_thread_if_any() {
-    underTest.activateDatabaseSettings(Collections.<String, String>emptyMap());
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_3);
-
-    underTest.load();
-
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_3);
-
-    underTest.setProperty(PROPERTY_3, PROPERTY_VALUE_3);
-
-    assertThat(underTest.getProperties()).contains(entry(PROPERTY_3, PROPERTY_VALUE_3));
-
-    underTest.unload();
-
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_3);
-
-    underTest.setProperty(PROPERTY_3, PROPERTY_VALUE_3);
-
-    assertThat(underTest.getProperties()).contains(entry(PROPERTY_3, PROPERTY_VALUE_3));
-  }
-
-  @Test
-  public void setProperties_sets_property_in_settings_specific_to_current_thread_if_any() {
-    underTest.activateDatabaseSettings(Collections.<String, String>emptyMap());
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_3);
-
-    underTest.load();
-
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_3);
-
-    underTest.setProperties(ImmutableMap.of(PROPERTY_3, PROPERTY_VALUE_3));
-
-    assertThat(underTest.getProperties()).contains(entry(PROPERTY_3, PROPERTY_VALUE_3));
-
-    underTest.unload();
-
-    assertThat(underTest.getProperties()).doesNotContainKey(PROPERTY_3);
-
-    underTest.setProperties(ImmutableMap.of(PROPERTY_3, PROPERTY_VALUE_3));
-
-    assertThat(underTest.getProperties()).contains(entry(PROPERTY_3, PROPERTY_VALUE_3));
-  }
-
-  @Test
-  public void getString_gets_property_value_in_settings_specific_to_current_thread_if_any() {
-    underTest.activateDatabaseSettings(Collections.<String, String>emptyMap());
-    assertThat(underTest.getString(THREAD_PROPERTY)).isNull();
-
-    rootProperties.setProperty(THREAD_PROPERTY, MAIN);
-    underTest.load();
-
-    assertThat(underTest.getString(THREAD_PROPERTY)).isEqualTo(MAIN);
-
-    underTest.unload();
-
-    assertThat(underTest.getString(THREAD_PROPERTY)).isNull();
-  }
-
-  @Test
-  public void hasKey_checks_property_key_in_settings_specific_to_current_thread_if_any() {
-    underTest.activateDatabaseSettings(Collections.<String, String>emptyMap());
-    assertThat(underTest.hasKey(THREAD_PROPERTY)).isFalse();
-
-    rootProperties.setProperty(THREAD_PROPERTY, MAIN);
-    underTest.load();
-
-    assertThat(underTest.hasKey(THREAD_PROPERTY)).isTrue();
-
-    underTest.unload();
-
-    assertThat(underTest.hasKey(THREAD_PROPERTY)).isFalse();
-  }
-
-  private abstract class CaptorThread extends Thread {
-    private final boolean callLoad;
-    private final CountDownLatch latch;
-
-    public CaptorThread(boolean callLoad) {
-      this.callLoad = callLoad;
-      this.latch = new CountDownLatch(1);
-    }
-
-    public void blockingExecute() throws InterruptedException {
-      this.start();
-      this.latch.await(5, SECONDS);
-    }
-
-    @Override
-    public void run() {
-      if (callLoad) {
-        try {
-          rootProperties.setProperty(THREAD_PROPERTY, CAPTOR);
-          underTest.load();
-          doCapture();
-          latch.countDown();
-        } finally {
-          underTest.unload();
-        }
-      } else {
-        doCapture();
-        latch.countDown();
-      }
-    }
-
-    protected abstract void doCapture();
-  }
-
-  private class PropertiesCaptorThread extends CaptorThread {
-    private Map<String, String> properties;
-
-    public PropertiesCaptorThread(boolean callLoad) {
-      super(callLoad);
-    }
-
-    protected void doCapture() {
-      this.properties = underTest.getProperties();
-    }
-  }
-
-  private class EncryptionCaptorThread extends CaptorThread {
-    private Encryption encryption;
-
-    public EncryptionCaptorThread(boolean callLoad) {
-      super(callLoad);
-    }
-
-    protected void doCapture() {
-      this.encryption = underTest.getEncryption();
-    }
-  }
-}
index 5637427b07eef619341a5ba6ebc7874c00e1e8aa..975bf7df0659bdf6379f7c5a4c5cf6c22fe7eb7a 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.ce.settings;
 
 import org.junit.Test;
+import org.sonar.server.setting.ThreadLocalSettings;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
index d9504ca21a2e0e0330e31979c7448f6272d0666e..eb946583b3f4f98f6df6529683241b8ab2c5000a 100644 (file)
@@ -25,7 +25,7 @@ import org.assertj.core.data.MapEntry;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
@@ -45,7 +45,7 @@ public class ActivityServiceTest {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester es = new EsTester(new ActivityIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new ActivityIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone().login();
index f3da030af2d35add01bf6e8341dbd8138cc9c4c2..daff5532474b953c9b9af50bd75916e42f21d0ac 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.activity.index;
 
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.NewIndex;
 
@@ -32,7 +32,7 @@ public class ActivityIndexDefinitionTest {
 
   @Test
   public void define() {
-    ActivityIndexDefinition def = new ActivityIndexDefinition(new Settings());
+    ActivityIndexDefinition def = new ActivityIndexDefinition(new MapSettings());
     def.define(underTest);
 
     assertThat(underTest.getIndices()).hasSize(1);
index 0c28bb6e3ef4333191cdc540bf8af5cb5e888c7b..c60aefe043ac67b26e1d1cf6a2d35af9413c4134 100644 (file)
@@ -24,7 +24,7 @@ import java.util.Date;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.activity.Activity;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.es.SearchOptions;
@@ -35,7 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class ActivityIndexTest {
 
   @Rule
-  public EsTester es = new EsTester(new ActivityIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new ActivityIndexDefinition(new MapSettings()));
 
   ActivityIndex underTest;
 
index e819ec3739808a52dc88d76ff7eda9c7ebaf35ef..00ff1be683cdf4b3f1344bcb2ea373fc5ecb6f70 100644 (file)
@@ -26,6 +26,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.process.DefaultProcessCommands;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -40,7 +41,7 @@ public class ProcessCommandWrapperImplTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
 
   @Test
   public void requestSQRestart_throws_IAE_if_process_index_property_not_set() throws Exception {
index b8646c4f6527eb1497b8b8c7ac5a98ab4985ff9e..8bcac5a50ef2a626a5a338299dd23c131c86702d 100644 (file)
@@ -35,6 +35,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -83,7 +84,7 @@ public class JwtHttpHandlerTest {
   HttpSession httpSession = mock(HttpSession.class);
 
   System2 system2 = mock(System2.class);
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   JwtSerializer jwtSerializer = mock(JwtSerializer.class);
   JwtCsrfVerifier jwtCsrfVerifier = mock(JwtCsrfVerifier.class);
 
index 022edfcf0584db3835fc81e481128540643d9900..0011a0b25651661e9a3711b606ed6a9adad21529 100644 (file)
@@ -20,9 +20,6 @@
 
 package org.sonar.server.authentication;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.authentication.JwtSerializer.JwtSession;
-
 import com.google.common.collect.ImmutableMap;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
@@ -36,6 +33,7 @@ import javax.crypto.spec.SecretKeySpec;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
@@ -43,24 +41,26 @@ import org.sonar.core.util.UuidFactory;
 import org.sonar.core.util.UuidFactoryImpl;
 import org.sonar.server.exceptions.UnauthorizedException;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.authentication.JwtSerializer.JwtSession;
+
 public class JwtSerializerTest {
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  static final String SECRET_KEY = "HrPSavOYLNNrwTY+SOqpChr7OwvbR/zbDLdVXRN0+Eg=";
+  static final String A_SECRET_KEY = "HrPSavOYLNNrwTY+SOqpChr7OwvbR/zbDLdVXRN0+Eg=";
 
   static final String USER_LOGIN = "john";
 
-  Settings settings = new Settings();
-  System2 system2 = System2.INSTANCE;
-  UuidFactory uuidFactory = UuidFactoryImpl.INSTANCE;
-
-  JwtSerializer underTest = new JwtSerializer(settings, system2, uuidFactory);
+  private Settings settings = new MapSettings();
+  private System2 system2 = System2.INSTANCE;
+  private UuidFactory uuidFactory = UuidFactoryImpl.INSTANCE;
+  private JwtSerializer underTest = new JwtSerializer(settings, system2, uuidFactory);
 
   @Test
   public void generate_token() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = underTest.encode(new JwtSession(USER_LOGIN, 10));
@@ -70,7 +70,8 @@ public class JwtSerializerTest {
 
   @Test
   public void generate_token_with_expiration_date() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
+
     underTest.start();
     Date now = new Date();
 
@@ -78,13 +79,13 @@ public class JwtSerializerTest {
 
     assertThat(token).isNotEmpty();
     Claims claims = underTest.decode(token).get();
-    // Check expiration date it set to more than 9 seconds in the futur
+    // Check expiration date it set to more than 9 seconds in the future
     assertThat(claims.getExpiration()).isAfterOrEqualsTo(new Date(now.getTime() + 9 * 1000));
   }
 
   @Test
   public void generate_token_with_property() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = underTest.encode(new JwtSession(USER_LOGIN, 10, ImmutableMap.of("custom", "property")));
@@ -96,7 +97,7 @@ public class JwtSerializerTest {
 
   @Test
   public void decode_token() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
     Date now = new Date();
 
@@ -107,20 +108,20 @@ public class JwtSerializerTest {
     assertThat(claims.getSubject()).isEqualTo(USER_LOGIN);
     assertThat(claims.getExpiration()).isNotNull();
     assertThat(claims.getIssuedAt()).isNotNull();
-    // Check expiration date it set to more than 19 minutes in the futur
+    // Check expiration date it set to more than 19 minutes in the future
     assertThat(claims.getExpiration()).isAfterOrEqualsTo(new Date(now.getTime() + 19 * 60 * 1000));
   }
 
   @Test
   public void return_no_token_when_expiration_date_is_reached() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = Jwts.builder()
       .setId("123")
       .setIssuedAt(new Date(system2.now()))
       .setExpiration(new Date(system2.now()))
-      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(SECRET_KEY))
+      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(A_SECRET_KEY))
       .compact();
 
     assertThat(underTest.decode(token)).isEmpty();
@@ -128,7 +129,7 @@ public class JwtSerializerTest {
 
   @Test
   public void return_no_token_when_secret_key_has_changed() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = Jwts.builder()
@@ -144,7 +145,7 @@ public class JwtSerializerTest {
 
   @Test
   public void fail_to_decode_token_when_no_id() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = Jwts.builder()
@@ -152,7 +153,7 @@ public class JwtSerializerTest {
       .setIssuer("sonarqube")
       .setIssuedAt(new Date(system2.now()))
       .setExpiration(new Date(system2.now() + 20 * 60 * 1000))
-      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(SECRET_KEY))
+      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(A_SECRET_KEY))
       .compact();
 
     expectedException.expect(UnauthorizedException.class);
@@ -162,7 +163,7 @@ public class JwtSerializerTest {
 
   @Test
   public void fail_to_decode_token_when_no_subject() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = Jwts.builder()
@@ -170,7 +171,7 @@ public class JwtSerializerTest {
       .setIssuer("sonarqube")
       .setIssuedAt(new Date(system2.now()))
       .setExpiration(new Date(system2.now() + 20 * 60 * 1000))
-      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(SECRET_KEY))
+      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(A_SECRET_KEY))
       .compact();
 
     expectedException.expect(UnauthorizedException.class);
@@ -180,7 +181,7 @@ public class JwtSerializerTest {
 
   @Test
   public void fail_to_decode_token_when_no_expiration_date() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = Jwts.builder()
@@ -188,7 +189,7 @@ public class JwtSerializerTest {
       .setIssuer("sonarqube")
       .setSubject(USER_LOGIN)
       .setIssuedAt(new Date(system2.now()))
-      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(SECRET_KEY))
+      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(A_SECRET_KEY))
       .compact();
 
     expectedException.expect(UnauthorizedException.class);
@@ -198,14 +199,14 @@ public class JwtSerializerTest {
 
   @Test
   public void fail_to_decode_token_when_no_creation_date() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     String token = Jwts.builder()
       .setId("123")
       .setSubject(USER_LOGIN)
       .setExpiration(new Date(system2.now() + 20 * 60 * 1000))
-      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(SECRET_KEY))
+      .signWith(SignatureAlgorithm.HS256, decodeSecretKey(A_SECRET_KEY))
       .compact();
 
     expectedException.expect(UnauthorizedException.class);
@@ -214,26 +215,27 @@ public class JwtSerializerTest {
   }
 
   @Test
-  public void generate_new_secret_key_in_start() throws Exception {
-    settings.setProperty("sonar.jwt.base64hs256secretKey", (String) null);
+  public void generate_new_secret_key_if_not_set_by_settings() throws Exception {
+    assertThat(underTest.getSecretKey()).isNull();
 
     underTest.start();
 
-    assertThat(settings.getString("sonar.auth.jwtBase64Hs256Secret")).isNotEmpty();
+    assertThat(underTest.getSecretKey()).isNotNull();
+    assertThat(underTest.getSecretKey().getAlgorithm()).isEqualTo(SignatureAlgorithm.HS256.getJcaName());
   }
 
   @Test
-  public void does_not_generate_new_secret_key_in_start_if_already_exists() throws Exception {
-    setDefaultSecretKey();
+  public void load_secret_key_from_settings() throws Exception {
+    setSecretKey(A_SECRET_KEY);
 
     underTest.start();
 
-    assertThat(settings.getString("sonar.auth.jwtBase64Hs256Secret")).isEqualTo(SECRET_KEY);
+    assertThat(settings.getString("sonar.auth.jwtBase64Hs256Secret")).isEqualTo(A_SECRET_KEY);
   }
 
   @Test
   public void refresh_token() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
 
     Date now = new Date();
@@ -264,7 +266,7 @@ public class JwtSerializerTest {
 
   @Test
   public void refresh_token_generate_a_new_hash() throws Exception {
-    setDefaultSecretKey();
+    setSecretKey(A_SECRET_KEY);
     underTest.start();
     String token = underTest.encode(new JwtSession(USER_LOGIN, 30));
     Optional<Claims> claims = underTest.decode(token);
@@ -298,12 +300,12 @@ public class JwtSerializerTest {
     underTest.refresh(new DefaultClaims(), 10);
   }
 
-  private void setDefaultSecretKey() {
-    settings.setProperty("sonar.auth.jwtBase64Hs256Secret", SECRET_KEY);
-  }
-
   private SecretKey decodeSecretKey(String encodedKey) {
     byte[] decodedKey = Base64.getDecoder().decode(encodedKey);
     return new SecretKeySpec(decodedKey, 0, decodedKey.length, SignatureAlgorithm.HS256.getJcaName());
   }
+
+  private void setSecretKey(String s) {
+    settings.setProperty("sonar.auth.jwtBase64Hs256Secret", s);
+  }
 }
index 45433607acb76fa035c4322e915aabd76834bed9..36682e422706f2e66348fb2e25ca70d1cf5f5971 100644 (file)
 
 package org.sonar.server.authentication;
 
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.rules.ExpectedException.none;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.sonar.db.user.UserTesting.newUserDto;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.mockito.ArgumentCaptor;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.security.Authenticator;
 import org.sonar.api.security.ExternalGroupsProvider;
@@ -48,6 +39,16 @@ import org.sonar.db.user.UserDto;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.user.SecurityRealmFactory;
 
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.rules.ExpectedException.none;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.db.user.UserTesting.newUserDto;
+
 public class RealmAuthenticatorTest {
 
   @Rule
@@ -61,7 +62,7 @@ public class RealmAuthenticatorTest {
   ArgumentCaptor<UserIdentity> userIdentityArgumentCaptor = ArgumentCaptor.forClass(UserIdentity.class);
   ArgumentCaptor<IdentityProvider> identityProviderArgumentCaptor = ArgumentCaptor.forClass(IdentityProvider.class);
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   SecurityRealmFactory securityRealmFactory = mock(SecurityRealmFactory.class);
   SecurityRealm realm = mock(SecurityRealm.class);
index 51d31dc2baf4b6951d0acbba10b5617105fedb9e..174d7252bac0078259929fda8438adba80bf9b47 100644 (file)
  */
 package org.sonar.server.authentication;
 
-import static com.google.common.collect.Sets.newHashSet;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
@@ -34,6 +29,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.server.authentication.UnauthorizedException;
 import org.sonar.api.server.authentication.UserIdentity;
 import org.sonar.api.utils.System2;
@@ -50,6 +46,11 @@ import org.sonar.server.user.NewUserNotifier;
 import org.sonar.server.user.UserUpdater;
 import org.sonar.server.user.index.UserIndexer;
 
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
 public class UserIdentityAuthenticatorTest {
 
   static String USER_LOGIN = "github-johndoo";
@@ -80,7 +81,7 @@ public class UserIdentityAuthenticatorTest {
   DbSession dbSession = dbTester.getSession();
   UserDao userDao = dbClient.userDao();
   GroupDao groupDao = dbClient.groupDao();
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   HttpServletRequest request = mock(HttpServletRequest.class);
   HttpServletResponse response = mock(HttpServletResponse.class);
index 5b0a13780fcab0c4fbb0d9ed99737075ee4c927e..9f5501b9f8674c114c2b7d5918df819dd09692f6 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -66,7 +67,7 @@ public class UserSessionInitializerTest {
   JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
   BasicAuthenticator basicAuthenticator = mock(BasicAuthenticator.class);
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   UserDto user = newUserDto();
 
@@ -178,13 +179,6 @@ public class UserSessionInitializerTest {
     verifyZeroInteractions(userSession);
   }
 
-  @Test
-  public void remove_user_session() throws Exception {
-    underTest.removeUserSession();
-
-    verify(userSession).remove();
-  }
-
   private void assertPathIsIgnored(String path) {
     when(request.getRequestURI()).thenReturn(path);
 
index ce7131d69dbd63f4b6f482727ee4bc039b1dcd1a..e37274ce3ceef540d539cd865f94c7ad6704824c 100644 (file)
@@ -73,7 +73,7 @@ public class LoginActionTest {
 
   @Before
   public void setUp() throws Exception {
-    threadLocalUserSession.remove();
+    threadLocalUserSession.unload();
     dbClient.userDao().insert(dbSession, user);
     dbSession.commit();
   }
index cefd822ab260ff8597c5d9f1da95a2827e8e3ab4..53ca6d7ab2766498ab7167373b55be13197fd26c 100644 (file)
 
 package org.sonar.server.authentication.ws;
 
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.sonar.db.user.UserTesting.newUserDto;
-
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Optional;
@@ -35,12 +29,19 @@ import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.authentication.BasicAuthenticator;
 import org.sonar.server.authentication.JwtHttpHandler;
 import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.test.JsonAssert;
 import org.sonarqube.ws.MediaTypes;
 
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.db.user.UserTesting.newUserDto;
+
 public class ValidateActionTest {
 
   StringWriter stringWriter = new StringWriter();
@@ -52,7 +53,7 @@ public class ValidateActionTest {
   BasicAuthenticator basicAuthenticator = mock(BasicAuthenticator.class);
   JwtHttpHandler jwtHttpHandler = mock(JwtHttpHandler.class);
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   ValidateAction underTest  = new ValidateAction(settings, basicAuthenticator, jwtHttpHandler);
 
index d22516d361e27f52a686a4c1d53fecd0d15b379d..69194e8f21684599aa9a2c69276eef2f22f3c0cb 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -71,7 +71,7 @@ public class IssuesActionTest {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester es = new EsTester(new IssueIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new IssueIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index 30a96caffe2f8030f075901dd62a6fdf68fec3fd..fb5e11792f9353997887962a62272bd0b44733da 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.scanner.protocol.input.ScannerInput.User;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.exceptions.UnauthorizedException;
@@ -46,7 +46,7 @@ public class UsersActionTest {
   public ExpectedException thrown = ExpectedException.none();
 
   @Rule
-  public EsTester es = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index c3c8ddb7548bd3096a5cd5679ae29cd2002f855c..c12d0b67c4b7b6a02beeab5145bd598c5ca0583b 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.MessageException;
 
 import static java.lang.Math.abs;
@@ -34,7 +35,7 @@ public class CeConfigurationImplTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
 
   @Test
   public void getWorkCount_returns_1_when_worker_property_is_not_defined() {
index 4bf77a708fb27cbf343f79275ead35fe5f47061f..dcc24b82d698490f27feacb95390433b2c34893f 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.core.config.PurgeConstants;
 import org.sonar.db.DbSession;
@@ -49,7 +50,7 @@ public class ProjectCleanerTest {
   private PurgeProfiler profiler = mock(PurgeProfiler.class);
   private DefaultPeriodCleaner periodCleaner = mock(DefaultPeriodCleaner.class);
   private PurgeListener purgeListener = mock(PurgeListener.class);
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
 
   @Before
   public void before() {
index 9424cd660bac459044b724867653377775b3100d..97f96f28539b8dc803a591f3617f20bfb97c3a6b 100644 (file)
@@ -28,12 +28,13 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.ce.measure.Component;
 import org.sonar.api.ce.measure.MeasureComputer;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.Duration;
 import org.sonar.core.issue.DefaultIssue;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRepositoryRule;
 import org.sonar.server.computation.task.projectanalysis.measure.Measure;
 import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule;
@@ -66,17 +67,18 @@ public class MeasureComputerContextImplTest {
   private static final String FILE_1_KEY = "fileKey";
   private static final int FILE_2_REF = 12342;
 
-  private static final org.sonar.server.computation.task.projectanalysis.component.Component FILE_1 = builder(org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE, FILE_1_REF)
-    .setKey(FILE_1_KEY)
-    .build();
+  private static final org.sonar.server.computation.task.projectanalysis.component.Component FILE_1 = builder(
+    org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE, FILE_1_REF)
+      .setKey(FILE_1_KEY)
+      .build();
 
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule()
     .setRoot(builder(org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT, PROJECT_REF).setKey("project")
       .addChildren(
         FILE_1,
-        builder(org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE, FILE_2_REF).setKey("fileKey2").build()
-      ).build());
+        builder(org.sonar.server.computation.task.projectanalysis.component.Component.Type.FILE, FILE_2_REF).setKey("fileKey2").build())
+      .build());
 
   @Rule
   public MetricRepositoryRule metricRepository = new MetricRepositoryRule()
@@ -85,8 +87,7 @@ public class MeasureComputerContextImplTest {
     .add(new MetricImpl(3, DOUBLE_METRIC_KEY, "double metric", Metric.MetricType.FLOAT))
     .add(new MetricImpl(4, LONG_METRIC_KEY, "long metric", Metric.MetricType.MILLISEC))
     .add(new MetricImpl(5, STRING_METRIC_KEY, "string metric", Metric.MetricType.STRING))
-    .add(new MetricImpl(6, BOOLEAN_METRIC_KEY, "boolean metric", Metric.MetricType.BOOL))
-    ;
+    .add(new MetricImpl(6, BOOLEAN_METRIC_KEY, "boolean metric", Metric.MetricType.BOOL));
 
   @Rule
   public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository);
@@ -104,7 +105,7 @@ public class MeasureComputerContextImplTest {
 
   @Test
   public void get_string_settings() throws Exception {
-    org.sonar.api.config.Settings serverSettings = new org.sonar.api.config.Settings();
+    org.sonar.api.config.Settings serverSettings = new MapSettings();
     serverSettings.setProperty("prop", "value");
     when(settingsRepository.getSettings(FILE_1)).thenReturn(serverSettings);
 
@@ -115,7 +116,7 @@ public class MeasureComputerContextImplTest {
 
   @Test
   public void get_string_array_settings() throws Exception {
-    org.sonar.api.config.Settings serverSettings = new org.sonar.api.config.Settings();
+    org.sonar.api.config.Settings serverSettings = new MapSettings();
     serverSettings.setProperty("prop", "1,3.4,8,50");
     when(settingsRepository.getSettings(FILE_1)).thenReturn(serverSettings);
 
index 12a97c0b66bbf17290db4442ec852558c016f4e7..c89fdb24d755430cd48b9badc6382ae1dc59c3f3 100644 (file)
@@ -23,16 +23,16 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.System2;
+import org.sonar.ce.settings.ProjectSettingsFactory;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.property.PropertiesDao;
 import org.sonar.db.property.PropertyDto;
-import org.sonar.server.setting.ProjectSettingsFactory;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT;
@@ -49,16 +49,15 @@ public class SettingsRepositoryTest {
 
   DbSession session;
 
-  Settings globalSettings;
+  MapSettings globalSettings;
 
   SettingsRepository underTest;
 
   @Before
   public void createDao() {
-    globalSettings = new Settings();
-    PropertiesDao propertiesDao = new PropertiesDao(dbTester.myBatis());
+    globalSettings = new MapSettings();
     session = dbClient.openSession(false);
-    underTest = new SettingsRepositoryImpl(new ProjectSettingsFactory(globalSettings, propertiesDao));
+    underTest = new SettingsRepositoryImpl(new ProjectSettingsFactory(globalSettings, dbClient));
   }
 
   @After
index d39ce43e130410b5afc8f6396096f86ba96905d4..b14e16a393bfeb866643956ed1f8c47cd234b9a6 100644 (file)
@@ -26,6 +26,7 @@ import java.util.Collections;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.duplications.block.Block;
@@ -58,7 +59,7 @@ public class IntegrateCrossProjectDuplicationsTest {
 
   static final String OTHER_FILE_KEY = "OTHER_FILE_KEY";
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   IntegrateCrossProjectDuplications underTest = new IntegrateCrossProjectDuplications(settings, duplicationRepository);
 
index 0953cb47d94ad795bef9aa7ee751c3f638d683c8..a47e6356333ce14a2ddc28b5638ab66cff5c4ba2 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.computation.task.projectanalysis.issue;
 
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction;
@@ -39,7 +39,7 @@ public class DebtCalculatorTest {
   @org.junit.Rule
   public RuleRepositoryRule ruleRepository = new RuleRepositoryRule().add(rule);
 
-  DebtCalculator underTest = new DebtCalculator(ruleRepository, new Durations(new Settings(), mock(I18n.class)));
+  DebtCalculator underTest = new DebtCalculator(ruleRepository, new Durations(new MapSettings(), mock(I18n.class)));
 
   @Test
   public void no_debt_if_function_is_not_defined() {
index 616f5918e3af1e8e3035a960bbb07f79bddfc96e..d52d228f8b6cfa93420000c26328fb98d0ea9598 100644 (file)
@@ -24,9 +24,10 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.user.index.UserDoc;
 import org.sonar.server.user.index.UserIndex;
 
@@ -40,7 +41,7 @@ public class DefaultAssigneeTest {
 
   TreeRootHolderRule rootHolder = mock(TreeRootHolderRule.class, Mockito.RETURNS_DEEP_STUBS);
   UserIndex userIndex = mock(UserIndex.class);
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   SettingsRepository settingsRepository = mock(SettingsRepository.class);
 
   DefaultAssignee underTest = new DefaultAssignee(rootHolder, userIndex, settingsRepository);
index de8301e91da924ec565613543e7f123891c3977b..aaf15f74b78891eda50ae5b1eea6a435644ef68c 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.server.computation.task.projectanalysis.issue;
 
 import java.util.Collections;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.server.es.EsTester;
@@ -36,7 +36,7 @@ import static org.junit.Assert.fail;
 public class ScmAccountToUserLoaderTest {
 
   @org.junit.Rule
-  public EsTester esTester = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   @org.junit.Rule
   public LogTester logTester = new LogTester();
index 36f61520aa546c77a349ec6cd06eefdfe712cd2d..d7ec31ea3ae292e91ea3f9bedff23fd3bcde589a 100644 (file)
@@ -28,11 +28,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.core.issue.DefaultIssue;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 
 import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -71,7 +72,7 @@ public class IssueFilterTest {
 
   @Test
   public void accept_everything_when_no_filter_properties() throws Exception {
-    IssueFilter underTest = newIssueFilter(new Settings());
+    IssueFilter underTest = newIssueFilter(new MapSettings());
 
     assertThat(underTest.accept(ISSUE_1, COMPONENT_1)).isTrue();
     assertThat(underTest.accept(ISSUE_2, COMPONENT_2)).isTrue();
@@ -188,7 +189,7 @@ public class IssueFilterTest {
   }
 
   private static Settings newSettings(List<String> exclusionsProperties, List<String> inclusionsProperties) {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     if (!exclusionsProperties.isEmpty()) {
       addProperties(exclusionsProperties, "ignore", settings);
     }
index f60f3d0e7d8c8f68696a905785aeb6db2f3484f1..4348dfe074a82d95a85ecab5cf31fd600600b819 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.utils.MessageException;
 
@@ -43,7 +44,7 @@ public class RatingSettingsTest {
 
   @Before
   public void setUp() {
-    settings = new Settings();
+    settings = new MapSettings();
   }
 
   @Test
index f3d32a813ff7d9292f167b94035bb73c90b760b3..ff5b54931b62a5d6eedcc80f5853216f6cb7ed78 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -38,10 +39,10 @@ import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.permission.PermissionRepository;
 import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.user.GroupRoleDto;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule;
 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent;
 import org.sonar.server.computation.task.step.ComputationStep;
 import org.sonar.server.es.EsTester;
@@ -62,7 +63,7 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
   private static final long SOME_DATE = 1000L;
 
   @Rule
-  public EsTester esTester = new EsTester(new IssueIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
@@ -77,7 +78,7 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
 
   DbClient dbClient = dbTester.getDbClient();
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   IssueAuthorizationIndexer issueAuthorizationIndexer;
 
index a723d96ad6fda9535f21699edbbd1931e6cb4680..8e6eb0ac92298bca10828e86798a195b13dc8e73 100644 (file)
@@ -23,13 +23,13 @@ import java.util.List;
 import org.elasticsearch.search.SearchHit;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.step.ComputationStep;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.test.db.TestTesting;
@@ -45,7 +45,7 @@ public class IndexTestsStepTest extends BaseStepTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester esTester = new EsTester(new TestIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new TestIndexDefinition(new MapSettings()));
 
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
index d0524a9bd0b0fee062f1eed6996e304118a55512..3b72acbd7dc83ff69659d88f1243769127647e62 100644 (file)
@@ -29,15 +29,16 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent;
 import org.sonar.server.computation.task.projectanalysis.period.Period;
 import org.sonar.server.computation.task.projectanalysis.period.PeriodsHolderImpl;
@@ -72,7 +73,7 @@ public class LoadPeriodsStepTest extends BaseStepTest {
 
   PeriodsHolderImpl periodsHolder = new PeriodsHolderImpl();
   DbClient dbClient = dbTester.getDbClient();
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   SettingsRepository settingsRepository = mock(SettingsRepository.class);
 
   LoadPeriodsStep underTest;
index 4c19104084298415d4a1e0bedcf0a212e2daabd8..bb5b6b5dd2aa85a7106b65f05002d2cf46f8ae52 100644 (file)
@@ -30,17 +30,18 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.purge.IdUuidPair;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
+import org.sonar.server.computation.dbcleaner.ProjectCleaner;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.MutableDbIdsRepositoryRule;
 import org.sonar.server.computation.task.projectanalysis.component.MutableDisabledComponentsHolder;
 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.ViewsComponent;
-import org.sonar.server.computation.dbcleaner.ProjectCleaner;
 import org.sonar.server.computation.task.step.ComputationStep;
 import org.sonar.server.util.WrapInSingleElementArray;
 
@@ -132,7 +133,7 @@ public class PurgeDatastoresStepTest extends BaseStepTest {
 
   private void verify_call_purge_method_of_the_purge_task(Component project) {
     treeRootHolder.setRoot(project);
-    when(settingsRepository.getSettings(project)).thenReturn(new Settings());
+    when(settingsRepository.getSettings(project)).thenReturn(new MapSettings());
     dbIdsRepository.setComponentId(project, PROJECT_ID);
 
     underTest.execute();
index ab1e9529d3cb0c7e2031ed8c745ad60734fa29d6..d956414fc9c7973fc57202ef66d56f2909b4a77f 100644 (file)
@@ -24,11 +24,11 @@ import java.util.Collections;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
-import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.computation.task.projectanalysis.component.Component;
 import org.sonar.server.computation.task.projectanalysis.component.ReportComponent;
 import org.sonar.server.computation.task.projectanalysis.component.SettingsRepository;
+import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule;
 import org.sonar.server.computation.task.projectanalysis.component.VisitException;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.Condition;
 import org.sonar.server.computation.task.projectanalysis.qualitygate.MutableQualityGateHolderRule;
@@ -64,7 +64,7 @@ public class QualityGateLoadingStepTest {
   public void execute_sets_default_QualityGate_when_project_has_no_settings() {
     ReportComponent root = ReportComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).addChildren(ReportComponent.builder(Component.Type.FILE, 2).build()).build();
     treeRootHolder.setRoot(root);
-    when(settingsRepository.getSettings(root)).thenReturn(new Settings());
+    when(settingsRepository.getSettings(root)).thenReturn(new MapSettings());
 
     underTest.execute();
 
@@ -83,7 +83,7 @@ public class QualityGateLoadingStepTest {
         .andMessage(format("Unsupported value (%s) in property sonar.qualitygate", "10 sds")));
 
     treeRootHolder.setRoot(PROJECT_ALONE);
-    when(settingsRepository.getSettings(PROJECT_ALONE)).thenReturn(new Settings().setProperty("sonar.qualitygate", "10 sds"));
+    when(settingsRepository.getSettings(PROJECT_ALONE)).thenReturn(new MapSettings().setProperty("sonar.qualitygate", "10 sds"));
 
     underTest.execute();
   }
@@ -91,7 +91,7 @@ public class QualityGateLoadingStepTest {
   @Test
   public void execute_sets_default_QualityGate_if_it_can_not_be_found_by_service() {
     treeRootHolder.setRoot(PROJECT_ALONE);
-    when(settingsRepository.getSettings(PROJECT_ALONE)).thenReturn(new Settings().setProperty("sonar.qualitygate", 10));
+    when(settingsRepository.getSettings(PROJECT_ALONE)).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10));
     when(qualityGateService.findById(10)).thenReturn(Optional.<QualityGate>absent());
 
     underTest.execute();
@@ -104,7 +104,7 @@ public class QualityGateLoadingStepTest {
     QualityGate qualityGate = new QualityGate(465, "name", Collections.<Condition>emptyList());
 
     treeRootHolder.setRoot(PROJECT_ALONE);
-    when(settingsRepository.getSettings(PROJECT_ALONE)).thenReturn(new Settings().setProperty("sonar.qualitygate", 10));
+    when(settingsRepository.getSettings(PROJECT_ALONE)).thenReturn(new MapSettings().setProperty("sonar.qualitygate", 10));
     when(qualityGateService.findById(10)).thenReturn(Optional.of(qualityGate));
 
     underTest.execute();
index 899cc95384e747fe7357392212369b7b2b1c8757..a03ad95ed4f7e3bfa35cf95cdcee5d4ec1feeb3d 100644 (file)
@@ -24,6 +24,8 @@ import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Settings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.core.permission.GlobalPermissions;
@@ -51,11 +53,11 @@ public class UpdateConfigurationActionTest {
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
 
-  DbClient dbClient = db.getDbClient();
-  PropertyDbTester propertyDb = new PropertyDbTester(db);
-  org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
+  private DbClient dbClient = db.getDbClient();
+  private PropertyDbTester propertyDb = new PropertyDbTester(db);
+  private Settings settings = new MapSettings();
 
-  WsActionTester ws = new WsActionTester(new UpdateConfigurationAction(dbClient, userSession, settings));
+  private WsActionTester ws = new WsActionTester(new UpdateConfigurationAction(dbClient, userSession, settings));
 
   @Test
   public void update_email_settings() throws Exception {
index 644bae28a0306c533e5583b1b5cec67001fc3de3..9a118f84b3c4d7b8fb0069b0cb0501b5980ca719 100644 (file)
@@ -28,6 +28,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.process.ProcessProperties;
@@ -43,7 +44,7 @@ public class EsClientProviderTest {
   @Rule
   public LogTester logTester = new LogTester();
 
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
   private EsClientProvider underTest = new EsClientProvider();
   private String localhost;
 
index 147b2c6ed311f059c6a2b7d3d9ae76075fdd8aba..f20e8d2ec4f25f74526f4b50e58bf096c5b5b4e0 100644 (file)
@@ -45,7 +45,7 @@ import org.elasticsearch.node.Node;
 import org.elasticsearch.node.NodeBuilder;
 import org.elasticsearch.search.SearchHit;
 import org.junit.rules.ExternalResource;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.core.platform.ComponentContainer;
 
 import static com.google.common.base.Preconditions.checkState;
@@ -68,7 +68,7 @@ public class EsTester extends ExternalResource {
 
     if (!indexDefinitions.isEmpty()) {
       container = new ComponentContainer();
-      container.addSingleton(new Settings());
+      container.addSingleton(new MapSettings());
       container.addSingletons(indexDefinitions);
       container.addSingleton(client);
       container.addSingleton(IndexDefinitions.class);
index bfbc9a8ca7b6ea3ba87d1974bd3a5f87e3824d92..4aa7301a860118763dbfa11c14a434f6b28b46c8 100644 (file)
  */
 package org.sonar.server.es;
 
+import java.io.IOException;
+import java.util.Map;
+import javax.annotation.CheckForNull;
 import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
 import org.elasticsearch.cluster.metadata.MappingMetaData;
 import org.elasticsearch.common.collect.ImmutableOpenMap;
 import org.junit.Rule;
 import org.junit.Test;
-
-import javax.annotation.CheckForNull;
-
-import java.io.IOException;
-import java.util.Map;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -42,7 +40,7 @@ public class IndexCreatorTest {
   public void create_index() throws Exception {
     assertThat(mappings()).isEmpty();
 
-    IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinition()}, new Settings());
+    IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinition()}, new MapSettings());
     registry.start();
     IndexCreator creator = new IndexCreator(es.client(), registry);
     creator.start();
@@ -67,7 +65,7 @@ public class IndexCreatorTest {
     assertThat(mappings()).isEmpty();
 
     // v1
-    IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinition()}, new Settings());
+    IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinition()}, new MapSettings());
     registry.start();
     IndexCreator creator = new IndexCreator(es.client(), registry);
     creator.start();
@@ -76,7 +74,7 @@ public class IndexCreatorTest {
     assertThat(hashV1).isNotEmpty();
 
     // v2
-    registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinitionV2()}, new Settings());
+    registry = new IndexDefinitions(new IndexDefinition[] {new FakeIndexDefinitionV2()}, new MapSettings());
     registry.start();
     creator = new IndexCreator(es.client(), registry);
     creator.start();
index 944a8af591e393050b2fa1b8865809af310ebb66..d08875bfc0f66a93dcd01b3d0366f879ca1bc19d 100644 (file)
@@ -25,6 +25,7 @@ import org.assertj.core.data.MapEntry;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.common.settings.Settings;
 import org.junit.Test;
+import org.sonar.api.config.MapSettings;
 import org.sonar.process.ProcessProperties;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -150,7 +151,7 @@ public class NewIndexTest {
   @Test
   public void default_shards_and_replicas() {
     NewIndex index = new NewIndex("issues");
-    index.configureShards(new org.sonar.api.config.Settings());
+    index.configureShards(new MapSettings());
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo(String.valueOf(NewIndex.DEFAULT_NUMBER_OF_SHARDS));
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
   }
@@ -158,7 +159,7 @@ public class NewIndexTest {
   @Test
   public void five_shards_and_one_replica_by_default_on_cluster() {
     NewIndex index = new NewIndex("issues");
-    org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
+    MapSettings settings = new MapSettings();
     settings.setProperty(ProcessProperties.CLUSTER_ENABLED, "true");
     index.configureShards(settings);
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo(String.valueOf(NewIndex.DEFAULT_NUMBER_OF_SHARDS));
@@ -168,7 +169,7 @@ public class NewIndexTest {
   @Test
   public void customize_number_of_shards() {
     NewIndex index = new NewIndex("issues");
-    org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
+    MapSettings settings = new MapSettings();
     settings.setProperty("sonar.search.issues.shards", "3");
     index.configureShards(settings);
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("3");
@@ -179,7 +180,7 @@ public class NewIndexTest {
   @Test
   public void customize_number_of_shards_and_replicas() {
     NewIndex index = new NewIndex("issues");
-    org.sonar.api.config.Settings settings = new org.sonar.api.config.Settings();
+    MapSettings settings = new MapSettings();
     settings.setProperty("sonar.search.issues.shards", "3");
     settings.setProperty("sonar.search.issues.replicas", "1");
     index.configureShards(settings);
index b5db7b389f0f500b3bc91f7327fc2084940106d4..a17eda281fdfd0daf41a0c69b85ac4ed4cac77ed 100644 (file)
@@ -25,7 +25,7 @@ import java.util.List;
 import org.elasticsearch.search.SearchHit;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
@@ -40,7 +40,7 @@ public class IssueAuthorizationIndexerTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester esTester = new EsTester(new IssueIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
 
   @Test
   public void index_nothing() {
index a10ad42129005f003baa4e9ccdc0c9911b2cbb74..1e1bc821cd7f9f11d7d36697be6b31cd97f762f4 100644 (file)
@@ -26,7 +26,7 @@ import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
@@ -56,7 +56,7 @@ import static org.sonarqube.ws.client.issue.IssueFilterParameters.FACET_MODE_EFF
 public class IssueIndexDebtTest {
 
   @Rule
-  public EsTester tester = new EsTester(new IssueIndexDefinition(new Settings()), new ViewIndexDefinition(new Settings()));
+  public EsTester tester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ViewIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index a81ebd39d525a224e31fbd81d6e55b6c70933d24..4e4f125f21ecab34b5971ebc59be02f0341e11a7 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.issue.index;
 
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.NewIndex;
 
@@ -32,7 +32,7 @@ public class IssueIndexDefinitionTest {
 
   @Test
   public void define() {
-    IssueIndexDefinition def = new IssueIndexDefinition(new Settings());
+    IssueIndexDefinition def = new IssueIndexDefinition(new MapSettings());
     def.define(underTest);
 
     assertThat(underTest.getIndices()).hasSize(1);
index 3bca5f4b8007bae2f825c0eeed72340ca12c53c8..db9145d7a85de3dd4530f634c9818af4053b073d 100644 (file)
@@ -33,7 +33,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.rule.RuleKey;
@@ -67,7 +67,7 @@ import static org.sonar.api.utils.DateUtils.parseDateTime;
 public class IssueIndexTest {
 
   @Rule
-  public EsTester tester = new EsTester(new IssueIndexDefinition(new Settings()), new ViewIndexDefinition(new Settings()));
+  public EsTester tester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ViewIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index 995909dcb3ff69bfa16d93c849738f10563021f5..aadc7ebde80b92a07a093e1aae8f5b62c8d184be 100644 (file)
@@ -29,7 +29,7 @@ import javax.annotation.Nonnull;
 import org.elasticsearch.search.SearchHit;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
@@ -45,7 +45,7 @@ public class IssueIndexerTest {
   private static final String A_PROJECT_UUID = "P1";
 
   @Rule
-  public EsTester esTester = new EsTester(new IssueIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
index a53bc8b8b3d9012b361668f8791a7827429c8b5b..40674b35c5a7c820f31a52d67dba69e15fa36345 100644 (file)
@@ -26,7 +26,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.Metric.ValueType;
 import org.sonar.api.utils.System2;
@@ -78,7 +78,7 @@ public class CreateActionTest {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester es = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   DbClient dbClient = db.getDbClient();
 
index 338f0efa3fd677afd5677fcc434eb81e3b0f6557..116490509f8cc201c5a087f9ba039ebf52c88cf0 100644 (file)
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -55,7 +55,7 @@ public class MetricsActionTest {
   private static final String DEFAULT_PROJECT_KEY = "project-key";
 
   @Rule
-  public EsTester es = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
   @Rule
index 8dd8a5e719ab81632382a8c989af34b42b4e5938..14857dbbf12d675cbce3554a4ca0d55e6cd5a92c 100644 (file)
@@ -25,7 +25,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.Metric.ValueType;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.DateUtils;
@@ -70,7 +70,7 @@ public class SearchActionTest {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester es = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   WsTester ws;
   DbClient dbClient = db.getDbClient();
index f17dcbd5d4922e266a9dcac12a7e6e1945696770..7db4d19f8d78e086054804841d67d64dd66bf621 100644 (file)
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.Metric.ValueType;
 import org.sonar.api.utils.System2;
 import org.sonar.core.permission.GlobalPermissions;
@@ -64,7 +64,7 @@ public class UpdateActionTest {
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
   @Rule
-  public EsTester es = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
   DbClient dbClient = db.getDbClient();
   DbSession dbSession = db.getSession();
   System2 system = mock(System2.class);
index c55d6d5d4e4a7baed14f7288765f7d961a27b9c3..2df7b3c2915fd266e4ea28206966436fa5b35924 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.notifications.Notification;
 import org.sonar.api.notifications.NotificationChannel;
 import org.sonar.db.DbClient;
@@ -69,7 +70,7 @@ public class NotificationServiceTest {
     when(qualityGateChange.getType()).thenReturn("qgate-changes");
     when(manager.getFromQueue()).thenReturn(notification).thenReturn(null);
 
-    Settings settings = new Settings().setProperty("sonar.notifications.delay", 1L);
+    Settings settings = new MapSettings().setProperty("sonar.notifications.delay", 1L);
 
     service = new NotificationService(settings, manager,
       dbClient,
@@ -207,7 +208,7 @@ public class NotificationServiceTest {
 
   @Test
   public void getDispatchers_empty() {
-    Settings settings = new Settings().setProperty("sonar.notifications.delay", 1L);
+    Settings settings = new MapSettings().setProperty("sonar.notifications.delay", 1L);
 
     service = new NotificationService(settings, manager, dbClient);
     assertThat(service.getDispatchers()).hasSize(0);
index 9b13fd4486e3412fcd6da9365e01f7bc81f91df2..321826beea7751ce78cbba8090d89b52c4fdd9b3 100644 (file)
@@ -27,7 +27,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -40,8 +40,8 @@ import org.sonar.db.component.ResourceTypesRule;
 import org.sonar.db.permission.GroupWithPermissionDto;
 import org.sonar.db.permission.OldPermissionQuery;
 import org.sonar.db.permission.PermissionRepository;
-import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.permission.UserWithPermissionDto;
+import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.GroupRoleDto;
 import org.sonar.db.user.UserDto;
@@ -103,7 +103,7 @@ public class ApplyTemplateActionTest {
     dbClient = db.getDbClient();
     dbSession = db.getSession();
 
-    PermissionRepository repository = new PermissionRepository(dbClient, new Settings());
+    PermissionRepository repository = new PermissionRepository(dbClient, new MapSettings());
     ComponentFinder componentFinder = new ComponentFinder(dbClient);
     PermissionService permissionService = new PermissionService(dbClient, repository, issueAuthorizationIndexer, userSession, componentFinder);
     PermissionDependenciesFinder permissionDependenciesFinder = new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes);
index e430cf624f2dddf3ee77a202e4d466ebdf154175..93f6763db18d90d301b3b72ec3ab6b8b3d1b08e6 100644 (file)
 
 package org.sonar.server.permission.ws.template;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.sonar.db.component.ComponentTesting.newDeveloper;
-import static org.sonar.db.component.ComponentTesting.newProjectDto;
-import static org.sonar.db.component.ComponentTesting.newView;
-import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto;
-import static org.sonar.db.user.GroupMembershipQuery.IN;
-import static org.sonar.db.user.GroupTesting.newGroupDto;
-import static org.sonar.db.user.UserTesting.newUserDto;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
-
 import com.google.common.base.Predicate;
 import com.google.common.collect.FluentIterable;
 import java.util.List;
@@ -41,7 +28,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.System2;
@@ -56,8 +43,8 @@ import org.sonar.db.component.ResourceTypesRule;
 import org.sonar.db.permission.GroupWithPermissionDto;
 import org.sonar.db.permission.OldPermissionQuery;
 import org.sonar.db.permission.PermissionRepository;
-import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.permission.UserWithPermissionDto;
+import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.user.GroupDbTester;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.GroupRoleDto;
@@ -76,6 +63,19 @@ import org.sonar.server.usergroups.ws.UserGroupFinder;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonar.db.component.ComponentTesting.newDeveloper;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.db.component.ComponentTesting.newView;
+import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto;
+import static org.sonar.db.user.GroupMembershipQuery.IN;
+import static org.sonar.db.user.GroupTesting.newGroupDto;
+import static org.sonar.db.user.UserTesting.newUserDto;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
+
 public class BulkApplyTemplateActionTest {
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone().login("login").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
@@ -103,7 +103,7 @@ public class BulkApplyTemplateActionTest {
 
   @Before
   public void setUp() {
-    PermissionRepository repository = new PermissionRepository(dbClient, new Settings());
+    PermissionRepository repository = new PermissionRepository(dbClient, new MapSettings());
     ComponentFinder componentFinder = new ComponentFinder(dbClient);
     PermissionService permissionService = new PermissionService(dbClient, repository, issueAuthorizationIndexer, userSession, componentFinder);
     PermissionDependenciesFinder permissionDependenciesFinder = new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes);
index 7576ca01a3d69cd3c462276dc75f2eb1512bf938..d1e8e3cf4959325a5ca3bfc9fa6f9ba54f6d49e7 100644 (file)
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceType;
@@ -39,24 +40,24 @@ import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRoot
 
 public class DefaultPermissionTemplateFinderTest {
 
-  ResourceTypes resourceTypes = mock(ResourceTypes.class);
-  Settings settings = new Settings();
-
-  DefaultPermissionTemplateFinder underTest;
+  private ResourceTypes resourceTypes = mock(ResourceTypes.class);
+  private Settings settings = new MapSettings();
+  private DefaultPermissionTemplateFinder underTest;
 
   @Before
   public void setUp() {
     underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes);
+    when(resourceTypes.getRoots()).thenReturn(rootResourceTypes());
+  }
+
+  @Test
+  public void get_default_template_uuids_in_settings() {
     settings
       .setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid")
       .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), "default-project-template-uuid")
       .setProperty(defaultRootQualifierTemplateProperty("DEV"), "default-dev-template-uuid")
       .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), "default-view-template-uuid");
-    when(resourceTypes.getRoots()).thenReturn(rootResourceTypes());
-  }
 
-  @Test
-  public void get_default_template_uuids_in_settings() {
     Set<String> result = underTest.getDefaultTemplateUuids();
 
     assertThat(result).containsOnly("default-project-template-uuid", "default-view-template-uuid", "default-dev-template-uuid");
@@ -64,9 +65,7 @@ public class DefaultPermissionTemplateFinderTest {
 
   @Test
   public void get_default_template_uuid_if_no_property() {
-    settings
-      .clear()
-      .setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid");
+    settings.setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid");
     underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes);
 
     Set<String> result = underTest.getDefaultTemplateUuids();
@@ -77,7 +76,6 @@ public class DefaultPermissionTemplateFinderTest {
   @Test
   public void get_default_project_template_uuid_if_no_property_for_views() {
     settings
-      .clear()
       .setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid")
       .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), "default-project-template-uuid")
       .setProperty(defaultRootQualifierTemplateProperty("DEV"), "default-dev-template-uuid");
index a6e3e9eec3b7639a31b350e9dfe3c1ac6d780246..039d95d9766803997d2a6f8c3130ecf01d8e11d6 100644 (file)
@@ -26,6 +26,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -33,8 +34,8 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ResourceTypesRule;
-import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto;
+import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.exceptions.UnauthorizedException;
@@ -75,7 +76,7 @@ public class SearchTemplatesActionTest {
   public void setUp() {
     i18n.setProjectPermissions();
 
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), UUID_EXAMPLE_01);
     settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), UUID_EXAMPLE_02);
     settings.setProperty(defaultRootQualifierTemplateProperty("DEV"), UUID_EXAMPLE_03);
index b4146f292386c20288548a1f7fa8231ca123ac97..d736f743cc9d3787fa3f3166dd8fdd96c7156186 100644 (file)
 package org.sonar.server.permission.ws.template;
 
 import java.util.List;
-import java.util.Properties;
 import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypes;
@@ -44,7 +43,7 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.i18n.I18nRule;
 import org.sonar.server.permission.ws.PermissionDependenciesFinder;
 import org.sonar.server.platform.PersistentSettings;
-import org.sonar.server.platform.ServerSettingsImpl;
+import org.sonar.server.platform.SettingsChangeNotifier;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usergroups.ws.UserGroupFinder;
 import org.sonar.server.ws.TestRequest;
@@ -82,7 +81,7 @@ public class SetDefaultTemplateActionTest {
   @Before
   public void setUp() {
     DbClient dbClient = db.getDbClient();
-    persistentSettings = new PersistentSettings(dbClient, new ServerSettingsImpl(new PropertyDefinitions(), new Properties()));
+    persistentSettings = new PersistentSettings(new MapSettings(), dbClient, new SettingsChangeNotifier());
     persistentSettings.saveProperty(DEFAULT_TEMPLATE_PROPERTY, "any-template-uuid");
     persistentSettings.saveProperty(defaultRootQualifierTemplateProperty(PROJECT), "any-template-uuid");
     persistentSettings.saveProperty(defaultRootQualifierTemplateProperty(VIEW), "any-view-template-uuid");
index e610810347afd1851e2cdd85d8bc7f2b56ac705b..df1bf2cb31afdb48e36c8e4cc429c44ee948520a 100644 (file)
@@ -21,7 +21,7 @@ package org.sonar.server.platform;
 
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.rule.RuleTesting;
@@ -40,9 +40,9 @@ public class BackendCleanupMediumTest {
 
   @Rule
   public EsTester esTester = new EsTester(
-    new RuleIndexDefinition(new Settings()),
-    new IssueIndexDefinition(new Settings()),
-    new ViewIndexDefinition(new Settings())
+    new RuleIndexDefinition(new MapSettings()),
+    new IssueIndexDefinition(new MapSettings()),
+    new ViewIndexDefinition(new MapSettings())
     );
 
   @Rule
index e80eaae4251fb2e60d8c3e198bed071b9ce50c4c..0239f6d8cbf225a5c43514fc11b0af50e84fabd7 100644 (file)
  */
 package org.sonar.server.platform;
 
-import com.google.common.collect.ImmutableMap;
-import java.util.Properties;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.config.Settings;
 import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
-import org.sonar.db.property.PropertiesDao;
-import org.sonar.db.property.PropertyDto;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
 
 public class PersistentSettingsTest {
-
   @Rule
-  public DbTester db = DbTester.create(System2.INSTANCE);
-
-  DbClient dbClient = db.getDbClient();
-  DbSession dbSession = db.getSession();
-
-  private PropertiesDao dao = dbClient.propertiesDao();
-  private ServerSettings settings = new ServerSettingsImpl(
-    new PropertyDefinitions(),
-    new Properties());
-
-  @Test
-  public void load_database_properties_at_startup() {
-    newGlobalProperty("in_db", "bar");
-
-    PersistentSettings persistentSettings = new PersistentSettings(dbClient, settings);
-    persistentSettings.start();
-
-    assertThat(settings.getString("in_db")).isEqualTo("bar");
-  }
-
-  @Test
-  public void saveProperty() {
-    PersistentSettings persistentSettings = new PersistentSettings(dbClient, settings);
-    persistentSettings.saveProperty("foo", "bar");
-
-    // kept in memory cache and persisted in db
-    assertThat(settings.getString("foo")).isEqualTo("bar");
-    verifyGlobalPropertyExists("foo", "bar");
-  }
-
-  @Test
-  public void deleteProperty() {
-    newGlobalProperty("foo", "bar_in_db");
-    settings.setProperty("foo", "bar");
-    assertThat(settings.hasKey("foo")).isTrue();
-
-    PersistentSettings persistentSettings = new PersistentSettings(dbClient, settings);
-    persistentSettings.deleteProperty("foo");
-
-    assertThat(settings.hasKey("foo")).isFalse();
-    verifyGlobalPropertyDoesNotExist("foo");
-  }
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+  private Settings delegate = new MapSettings();
+  private SettingsChangeNotifier changeNotifier = mock(SettingsChangeNotifier.class);
+  private PersistentSettings underTest = new PersistentSettings(delegate, dbTester.getDbClient(), changeNotifier);
 
   @Test
-  public void deleteProperties() {
-    newGlobalProperty("in_db1", "foo");
-    newGlobalProperty("in_db2", "bar");
-    settings.setProperty("foo", "bar");
-    assertThat(settings.hasKey("foo")).isTrue();
+  public void insert_property_into_database_and_notify_extensions() {
+    assertThat(underTest.getString("foo")).isNull();
 
-    PersistentSettings persistentSettings = new PersistentSettings(dbClient, settings);
-    persistentSettings.deleteProperties();
+    underTest.saveProperty("foo", "bar");
 
-    assertThat(settings.getProperties()).isEmpty();
-    assertThat(dao.selectGlobalProperties()).isEmpty();
+    assertThat(underTest.getString("foo")).isEqualTo("bar");
+    assertThat(dbTester.getDbClient().propertiesDao().selectGlobalProperty("foo").getValue()).isEqualTo("bar");
+    verify(changeNotifier).onGlobalPropertyChange("foo", "bar");
   }
 
   @Test
-  public void shortcuts_on_settings() {
-    settings.setProperty("foo", "bar");
-    assertThat(settings.hasKey("foo")).isTrue();
+  public void delete_property_from_database_and_notify_extensions() {
+    underTest.saveProperty("foo", "bar");
+    underTest.saveProperty("foo", null);
 
-    PersistentSettings persistentSettings = new PersistentSettings(dbClient, settings);
-
-    assertThat(persistentSettings.getProperties()).isEqualTo(settings.getProperties());
-    assertThat(persistentSettings.getString("foo")).isEqualTo("bar");
-    assertThat(persistentSettings.getSettings()).isEqualTo(settings);
+    assertThat(underTest.getString("foo")).isNull();
+    assertThat(dbTester.getDbClient().propertiesDao().selectGlobalProperty("foo")).isNull();
+    verify(changeNotifier).onGlobalPropertyChange("foo", null);
   }
 
   @Test
-  public void saveProperties() {
-    PersistentSettings persistentSettings = new PersistentSettings(dbClient, settings);
-    ImmutableMap<String, String> props = ImmutableMap.of("foo", "bar");
-    persistentSettings.saveProperties(props);
-
-    assertThat(settings.getString("foo")).isEqualTo("bar");
-    verifyGlobalPropertyExists("foo", "bar");
+  public void getSettings_returns_delegate() {
+    assertThat(underTest.getSettings()).isSameAs(delegate);
   }
-
-  private PropertyDto newGlobalProperty(String key, String value) {
-    PropertyDto propertyDto = new PropertyDto().setKey(key).setValue(value);
-    dao.insertProperty(dbSession, propertyDto);
-    dbSession.commit();
-    return propertyDto;
-  }
-
-  private void verifyGlobalPropertyExists(String key, String value){
-    PropertyDto propertyDto = dao.selectGlobalProperty(dbSession, key);
-    assertThat(propertyDto).isNotNull();
-    assertThat(propertyDto.getValue()).isEqualTo(value);
-    assertThat(propertyDto.getUserId()).isNull();
-    assertThat(propertyDto.getResourceId()).isNull();
-  }
-
-  private void verifyGlobalPropertyDoesNotExist(String key){
-    assertThat(dao.selectGlobalProperty(dbSession, key)).isNull();
-  }
-
 }
index f95f896e3a9aaf6769ab20eac80ac501f3d82435..c056a1c502f9472d8606b03f252ba4e67c86c37e 100644 (file)
@@ -23,6 +23,7 @@ import com.google.common.base.Optional;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -36,7 +37,7 @@ public class ServerIdLoaderTest {
   private static final String AN_IP = "1.2.3.4";
   public static final String AN_ORGANISATION = "corp";
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   ServerIdGenerator idGenerator = mock(ServerIdGenerator.class);
   ServerIdLoader underTest = new ServerIdLoader(settings, idGenerator);
 
index 4eefc54c7d846f1c9b815a4decf087eb225040c4..1231868b60a1bffeb6a758d2e810441577f04ac5 100644 (file)
@@ -27,6 +27,7 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.SonarRuntime;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.Version;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -35,7 +36,7 @@ import static org.mockito.Mockito.when;
 
 public class ServerImplTest {
 
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
   private StartupMetadata state = mock(StartupMetadata.class);
   private ServerFileSystem fs = mock(ServerFileSystem.class);
   private UrlSettings urlSettings = mock(UrlSettings.class);
index 9ad9e4d5001c39b83513ebbcc8182ed5f286c19d..d31ce54dfc88bf937d7e069b8699d2766ae46483 100644 (file)
@@ -29,6 +29,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.process.LogbackHelper;
@@ -46,7 +47,7 @@ public class ServerLoggingTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   ServerLogging underTest = new ServerLogging(settings);
 
   @Rule
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java
deleted file mode 100644 (file)
index f06f5ed..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.platform;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.config.PropertyDefinitions;
-
-import java.util.Map;
-import java.util.Properties;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ServerSettingsTest {
-
-  Properties properties;
-
-  ServerSettingsImpl settings;
-
-  @Before
-  public void before() {
-    properties = new Properties();
-    properties.put("hello", "world");
-    properties.put("in_file", "true");
-    properties.put("ServerSettingsTestEnv", "in_file");
-    settings = new ServerSettingsImpl(new PropertyDefinitions(), properties);
-  }
-
-  @Test
-  public void load_properties_file() {
-    assertThat(settings.getString("hello")).isEqualTo("world");
-  }
-
-  @Test
-  public void activate_database_settings() {
-    Map<String, String> databaseProperties = ImmutableMap.of("in_db", "true");
-    settings.activateDatabaseSettings(databaseProperties);
-
-    assertThat(settings.getString("in_db")).isEqualTo("true");
-  }
-
-  @Test
-  public void file_settings_override_db_settings() {
-    assertThat(settings.getString("in_file")).isEqualTo("true");
-
-    Map<String, String> databaseProperties = ImmutableMap.of("in_file", "false");
-    settings.activateDatabaseSettings(databaseProperties);
-
-    assertThat(settings.getString("in_file")).isEqualTo("true");
-  }
-
-}
index b507ea688d131890e4f0bbdd94622df4ee6d4c84..364d0126b17c517ee0596060d5cff3e6328dd851 100644 (file)
  */
 package org.sonar.server.platform;
 
-import java.util.Properties;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
@@ -40,9 +38,8 @@ public class StartupMetadataPersisterTest {
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
-  private PersistentSettings persistentSettings = new PersistentSettings(dbTester.getDbClient(), new ServerSettingsImpl(new PropertyDefinitions(), new Properties()));
   private StartupMetadata metadata = new StartupMetadata("an_id", 123_456_789L);
-  private StartupMetadataPersister underTest = new StartupMetadataPersister(metadata, persistentSettings);
+  private StartupMetadataPersister underTest = new StartupMetadataPersister(metadata, dbTester.getDbClient());
 
   @Test
   public void persist_metadata_at_startup() {
index 5363cf850d153f755e9654388c08c78551116ef6..9b3348860064ec75822145b6fc15af61cb4468be 100644 (file)
  */
 package org.sonar.server.platform;
 
-import java.util.Properties;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.SonarQubeSide;
 import org.sonar.api.SonarRuntime;
-import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.internal.SonarRuntimeImpl;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
@@ -41,7 +39,6 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
-
 public class StartupMetadataProviderTest {
 
   private static final long A_DATE = 1_500_000_000_000L;
@@ -110,8 +107,7 @@ public class StartupMetadataProviderTest {
   }
 
   private void testLoadingFromDatabase(SonarRuntime runtime, boolean isStartupLeader) {
-    PersistentSettings persistentSettings = new PersistentSettings(dbTester.getDbClient(), new ServerSettingsImpl(new PropertyDefinitions(), new Properties()));
-    new StartupMetadataPersister(new StartupMetadata(AN_ID, A_DATE), persistentSettings).start();
+    new StartupMetadataPersister(new StartupMetadata(AN_ID, A_DATE), dbTester.getDbClient()).start();
     cluster.setStartupLeader(isStartupLeader);
 
     StartupMetadata metadata = underTest.provide(uuidFactory, system, runtime, cluster, dbTester.getDbClient());
index 0ef1d5c41637ec360d9f7be59172494f3ef57cad..042b78fbaec52a6cd12d202d3645b9ccd5d7ba09 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.core.config.CorePropertyDefinitions;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -38,7 +39,7 @@ public class UrlSettingsTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  private Settings settings = new Settings(new PropertyDefinitions(CorePropertyDefinitions.all()));
+  private Settings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all()));
 
   @Test
   public void use_default_context_path() {
index e2f086eceb543e2569b617436937333d99f7197c..1bd69f626aec208298971be02f7bdf476c8058dd 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -32,7 +33,7 @@ public class ClusterImplTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  private Settings settings = new Settings(new PropertyDefinitions(ClusterProperties.definitions()));
+  private Settings settings = new MapSettings(new PropertyDefinitions(ClusterProperties.definitions()));
 
   @Test
   public void cluster_is_disabled_by_default() {
index 7c7ec08bd159a8712578d483e719f9ca421b014f..ccddae78b79280956d6a7bccece6241fa3ffc492 100644 (file)
@@ -21,9 +21,8 @@ package org.sonar.server.platform.db;
 
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.database.DatabaseProperties;
-import org.sonar.server.platform.db.EmbeddedDatabase;
-import org.sonar.server.platform.db.EmbeddedDatabaseFactory;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -31,7 +30,7 @@ import static org.mockito.Mockito.verify;
 
 public class EmbeddedDatabaseFactoryTest {
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
 
   @Test
   public void should_start_and_stop_tcp_h2_database() {
index fb17b9ee86b79519bfd03412b9052519bb61464f..1a36d75951fca83ef6d7e8bbc9416e682ff0e53c 100644 (file)
@@ -28,10 +28,9 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.junit.rules.Timeout;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.process.NetworkUtils;
-import org.sonar.server.platform.db.EmbeddedDatabase;
 
 import static junit.framework.Assert.fail;
 import static org.sonar.api.database.DatabaseProperties.PROP_EMBEDDED_PORT;
@@ -64,7 +63,7 @@ public class EmbeddedDatabaseTest {
 
   @Test
   public void start_fails_with_IAE_if_property_Data_Path_is_not_set() {
-    EmbeddedDatabase underTest = new EmbeddedDatabase(new Settings());
+    EmbeddedDatabase underTest = new EmbeddedDatabase(new MapSettings());
 
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("Missing property " + PATH_DATA);
@@ -74,7 +73,7 @@ public class EmbeddedDatabaseTest {
 
   @Test
   public void start_fails_with_IAE_if_property_Data_Path_is_empty() {
-    EmbeddedDatabase underTest = new EmbeddedDatabase(new Settings()
+    EmbeddedDatabase underTest = new EmbeddedDatabase(new MapSettings()
       .setProperty(PATH_DATA, ""));
 
     expectedException.expect(IllegalArgumentException.class);
@@ -85,7 +84,7 @@ public class EmbeddedDatabaseTest {
 
   @Test
   public void start_fails_with_IAE_if_JDBC_URL_settings_is_not_set() throws IOException {
-    EmbeddedDatabase underTest = new EmbeddedDatabase(new Settings()
+    EmbeddedDatabase underTest = new EmbeddedDatabase(new MapSettings()
       .setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath()));
 
     expectedException.expect(IllegalArgumentException.class);
@@ -96,7 +95,7 @@ public class EmbeddedDatabaseTest {
 
   @Test
   public void start_fails_with_IAE_if_embedded_port_settings_is_not_set() throws IOException {
-    EmbeddedDatabase underTest = new EmbeddedDatabase(new Settings()
+    EmbeddedDatabase underTest = new EmbeddedDatabase(new MapSettings()
       .setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
       .setProperty(PROP_URL, "jdbc url"));
 
@@ -109,7 +108,7 @@ public class EmbeddedDatabaseTest {
   @Test
   public void start_ignores_URL_to_create_database_and_uses_default_username_and_password_when_then_are_not_set() throws IOException {
     int port = NetworkUtils.freePort();
-    underTest = new EmbeddedDatabase(new Settings()
+    underTest = new EmbeddedDatabase(new MapSettings()
       .setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
       .setProperty(PROP_URL, "jdbc url")
       .setProperty(PROP_EMBEDDED_PORT, "" + port));
@@ -122,7 +121,7 @@ public class EmbeddedDatabaseTest {
   @Test
   public void start_creates_db_with_specified_user_and_password() throws IOException {
     int port = NetworkUtils.freePort();
-    underTest = new EmbeddedDatabase(new Settings()
+    underTest = new EmbeddedDatabase(new MapSettings()
       .setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
       .setProperty(PROP_URL, "jdbc url")
       .setProperty(PROP_EMBEDDED_PORT, "" + port)
@@ -137,7 +136,7 @@ public class EmbeddedDatabaseTest {
   @Test
   public void start_supports_in_memory_H2_JDBC_URL() throws IOException {
     int port = NetworkUtils.freePort();
-    underTest = new EmbeddedDatabase(new Settings()
+    underTest = new EmbeddedDatabase(new MapSettings()
       .setProperty(PATH_DATA, temporaryFolder.newFolder().getAbsolutePath())
       .setProperty(PROP_URL, "jdbc:h2:mem:sonar")
       .setProperty(PROP_EMBEDDED_PORT, "" + port)
index 911aed32594980af816cf92bd5ffd0b184a037f0..4232eff33faf33a9996048747a436143430dff7a 100644 (file)
@@ -23,7 +23,7 @@ import java.util.Map;
 import org.elasticsearch.cluster.health.ClusterHealthStatus;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.es.NewIndex;
 import org.sonar.server.issue.index.IssueIndexDefinition;
@@ -33,7 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class EsMonitorTest {
 
   @Rule
-  public EsTester esTester = new EsTester(new IssueIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()));
 
   EsMonitor underTest = new EsMonitor(esTester.client());
 
index 07e49e6d04b34d009addbc4984552ee86cc0d8b4..c974952491e098ef8f66e56353a389f46978b5fc 100644 (file)
@@ -25,6 +25,7 @@ import org.sonar.api.PropertyType;
 import org.sonar.api.config.PropertyDefinition;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.apache.commons.lang.StringUtils.repeat;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -35,7 +36,7 @@ public class SettingsMonitorTest {
   private static final String PASSWORD_PROPERTY = "sonar.password";
 
   PropertyDefinitions defs = new PropertyDefinitions(PropertyDefinition.builder(PASSWORD_PROPERTY).type(PropertyType.PASSWORD).build());
-  Settings settings = new Settings(defs);
+  Settings settings = new MapSettings(defs);
   SettingsMonitor underTest = new SettingsMonitor(settings);
 
   @Test
index aa50419bf76e1869a78c1f2a82490273a85628f0..60b0ffc5b2ad47388fba67e03d4156754b5b4a9f 100644 (file)
@@ -28,6 +28,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.platform.Server;
 import org.sonar.api.security.SecurityRealm;
 import org.sonar.api.utils.log.LoggerLevel;
@@ -55,7 +56,7 @@ public class SonarQubeMonitorTest {
   @Rule
   public IdentityProviderRepositoryRule identityProviderRepository = new IdentityProviderRepositoryRule();
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   Server server = mock(Server.class);
   ServerIdLoader serverIdLoader = mock(ServerIdLoader.class, RETURNS_DEEP_STUBS);
   ServerLogging serverLogging = mock(ServerLogging.class);
index c45b101dd55e2a555232aead1e4ea83a2b65fe05..3975e72c25da3822a7ce5ce02094b4b06a7a3021 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.rules.ExpectedException;
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.api.web.UserRole;
@@ -48,7 +49,7 @@ public class RestartActionTest {
   @Rule
   public LogTester logTester = new LogTester();
 
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
   private Platform platform = mock(Platform.class);
   private ProcessCommandWrapper processCommandWrapper = mock(ProcessCommandWrapper.class);
   private RestartFlagHolder restartFlagHolder = mock(RestartFlagHolder.class);
index 8e0ce1dcf36808cdafae8f1de7e5e63b3b947277..1ec85af5dd80fc5de237341f933a93c27b0cab53 100644 (file)
@@ -24,6 +24,7 @@ import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.SonarException;
 import org.sonar.api.utils.UriReader;
@@ -41,18 +42,16 @@ import static org.mockito.Mockito.when;
 
 public class UpdateCenterClientTest {
 
-  static final String BASE_URL = "http://update.sonarsource.org";
-  UriReader reader;
-  Settings settings;
-
-  UpdateCenterClient underTest;
+  private static final String BASE_URL = "http://update.sonarsource.org";
+  private UriReader reader = mock(UriReader.class);
+  private Settings settings = new MapSettings();
+  private UpdateCenterClient underTest;
 
   @Before
   public void startServer() throws Exception {
     reader = mock(UriReader.class);
-    settings = new Settings()
-      .setProperty(UpdateCenterClient.URL_PROPERTY, BASE_URL)
-      .setProperty(UpdateCenterClient.ACTIVATION_PROPERTY, true);
+    settings.setProperty(UpdateCenterClient.URL_PROPERTY, BASE_URL);
+    settings.setProperty(UpdateCenterClient.ACTIVATION_PROPERTY, true);
     underTest = new UpdateCenterClient(reader, settings);
   }
 
index 3e92da3db202c16dcfa86ab9d5c445e287d7497c..a4a7c29cc9230aae7e7e561300a5d7f67f2b44c4 100644 (file)
@@ -24,7 +24,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypes;
@@ -75,8 +75,8 @@ public class BulkDeleteActionTest {
   public DbTester db = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester es = new EsTester(new IssueIndexDefinition(new Settings()),
-    new TestIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new IssueIndexDefinition(new MapSettings()),
+    new TestIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index 4adf0859344732876ca5ca3f86e4cbf855eceffe..cbabaf2fa2e1d712f951a97485a27a90bde24123 100644 (file)
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypes;
@@ -72,8 +72,8 @@ public class DeleteActionTest {
 
   @Rule
   public EsTester es = new EsTester(
-    new IssueIndexDefinition(new Settings()),
-    new TestIndexDefinition(new Settings()));
+    new IssueIndexDefinition(new MapSettings()),
+    new TestIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index 9d8e25947c146fa82a7f49c97bc0d95364a012f4..8d07a418e9d47233552d9fb028bf66dee9193cfa 100644 (file)
@@ -34,7 +34,6 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Metric;
 import org.sonar.api.measures.Metric.ValueType;
@@ -90,7 +89,6 @@ public class QualityGatesTest {
   PropertiesDao propertiesDao = mock(PropertiesDao.class);
   ComponentDao componentDao = mock(ComponentDao.class);
   MetricFinder metricFinder = mock(MetricFinder.class);
-  Settings settings = new Settings();
 
   QualityGates underTest;
 
@@ -104,8 +102,6 @@ public class QualityGatesTest {
 
   @Before
   public void initialize() {
-    settings.clear();
-
     when(dbClient.openSession(false)).thenReturn(dbSession);
     when(dbClient.qualityGateDao()).thenReturn(dao);
     when(dbClient.gateConditionDao()).thenReturn(conditionDao);
@@ -114,7 +110,7 @@ public class QualityGatesTest {
 
     when(componentDao.selectOrFailById(eq(dbSession), anyLong())).thenReturn(newProjectDto(PROJECT_UUID).setId(1L).setKey(PROJECT_KEY));
 
-    underTest = new QualityGates(dbClient, metricFinder, userSessionRule, settings);
+    underTest = new QualityGates(dbClient, metricFinder, userSessionRule);
 
     userSessionRule.set(authorizedProfileAdminUserSession);
   }
@@ -228,7 +224,7 @@ public class QualityGatesTest {
   }
 
   @Test
-  public void should_select_default_qgate_and_update_settings() {
+  public void should_select_default_qgate() {
     long defaultId = QUALITY_GATE_ID;
     String defaultName = "Default Name";
     when(dao.selectById(defaultId)).thenReturn(new QualityGateDto().setId(defaultId).setName(defaultName));
@@ -241,17 +237,6 @@ public class QualityGatesTest {
 
     assertThat(propertyCaptor.getValue().getKey()).isEqualTo("sonar.qualitygate");
     assertThat(propertyCaptor.getValue().getValue()).isEqualTo("42");
-    assertThat(settings.getLong("sonar.qualitygate")).isEqualTo(42);
-  }
-
-  @Test
-  public void should_unset_default_qgate_and_unset_in_settings() {
-    settings.setProperty("sonar.qualitygate", 42l);
-
-    underTest.setDefault(null);
-
-    verify(propertiesDao).deleteGlobalProperty("sonar.qualitygate");
-    assertThat(settings.hasKey("sonar.qualitygate")).isFalse();
   }
 
   @Test
index 91b3a0eb0717f0e22b9e9359cf74cc83646e5b43..b71b39365269a465f883e2fc6edc198d01b74a84 100644 (file)
@@ -24,7 +24,6 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
 import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -64,7 +63,7 @@ public class DeselectActionTest {
   DbSession dbSession = db.getSession();
   ComponentDbTester componentDb = new ComponentDbTester(db);
 
-  QualityGates qualityGates = new QualityGates(dbClient, mock(MetricFinder.class), userSession, mock(Settings.class));
+  QualityGates qualityGates = new QualityGates(dbClient, mock(MetricFinder.class), userSession);
 
   WsActionTester ws;
 
index 17c1b684a1570f0658331061b55ba0a7f929c162..c0c3931d71570dcdfd611868dcbf77e38e9f22c9 100644 (file)
@@ -26,7 +26,6 @@ import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
 import org.sonar.api.measures.MetricFinder;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -71,7 +70,7 @@ public class GetByProjectActionTest {
 
   private WsActionTester ws = new WsActionTester(
     new GetByProjectAction(userSession, dbClient, new ComponentFinder(dbClient),
-      new QualityGates(dbClient, mock(MetricFinder.class), mock(UserSession.class), mock(Settings.class))));
+      new QualityGates(dbClient, mock(MetricFinder.class), mock(UserSession.class))));
 
   @Test
   public void json_example() {
index d81d64044655fd3802a410e3bbe5bcd8406e9f24..520130d4013b9d32df597772cf69982aa40b66c3 100644 (file)
@@ -27,7 +27,7 @@ import java.util.Map;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.db.qualityprofile.ActiveRuleKey;
 import org.sonar.db.rule.RuleTesting;
@@ -58,7 +58,7 @@ public class ActiveRuleIndexTest {
   private static final String QUALITY_PROFILE_KEY2 = "qp2";
 
   @Rule
-  public EsTester tester = new EsTester(new RuleIndexDefinition(new Settings()));
+  public EsTester tester = new EsTester(new RuleIndexDefinition(new MapSettings()));
 
   ActiveRuleIndex index;
   ActiveRuleIndexer activeRuleIndexer;
index 578b5778cac34960ec478a877a83472877491f91..de3fd69d1eeb59b18f06e74b488d71311f3a04a0 100644 (file)
@@ -24,7 +24,7 @@ import java.util.Arrays;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.utils.System2;
@@ -58,7 +58,7 @@ public class ActiveRuleIndexerTest {
   static final String QUALITY_PROFILE_KEY2 = "qp2";
 
   @Rule
-  public EsTester esTester = new EsTester(new RuleIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
index 30893c9a2a46117cfa83ce8664a5841910704a94..f1eb53c0f0138e272dc662c631bc01471b817905 100644 (file)
@@ -26,7 +26,7 @@ import org.joda.time.DateTime;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.DateUtils;
@@ -61,7 +61,7 @@ public class ChangelogActionTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester esTester = new EsTester(new ActivityIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new ActivityIndexDefinition(new MapSettings()));
 
   private DbClient db = dbTester.getDbClient();
   private DbSession dbSession = dbTester.getSession();
index a78379b87c138b94ec8b795be0b12adcff1b643c..9d456267d05ca68c14b49b91b529f03121d94809 100644 (file)
@@ -23,7 +23,7 @@ import java.util.Date;
 import java.util.List;
 import org.junit.Before;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Language;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.rule.RuleKey;
@@ -69,7 +69,7 @@ public class RegisterRulesTest {
   public DbTester dbTester = DbTester.create(system);
 
   @org.junit.Rule
-  public EsTester esTester = new EsTester(new RuleIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
 
   RuleActivator ruleActivator = mock(RuleActivator.class);
 
index 20cc59eed0f999e43fe3a1d34883ffe317db8d18..c6d7dc6d217c02e36ac3477ec1244def7fff32fb 100644 (file)
@@ -26,6 +26,7 @@ import org.elasticsearch.action.admin.indices.analyze.AnalyzeResponse;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.process.ProcessProperties;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.es.IndexDefinition;
@@ -39,7 +40,7 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.INDEX;
 
 public class RuleIndexDefinitionTest {
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   RuleIndexDefinition underTest = new RuleIndexDefinition(settings);
 
   @Rule
index ac9cfd29fc8b42223cf72cf6ef66db754e667e97..6dac4f8649354db5ad550b387fdc2283859bc91c 100644 (file)
@@ -28,7 +28,7 @@ import org.elasticsearch.search.SearchHit;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rules.RuleType;
@@ -76,7 +76,7 @@ public class RuleIndexTest {
   static final String QUALITY_PROFILE_KEY2 = "qp2";
 
   @Rule
-  public EsTester tester = new EsTester(new RuleIndexDefinition(new Settings()));
+  public EsTester tester = new EsTester(new RuleIndexDefinition(new MapSettings()));
 
   RuleIndex index;
   RuleIndexer ruleIndexer;
index a23f9c1e5e65d7c2a087bd560f97cfd9ddb494d9..03d352f39295f6bb5eb9d8f26ceadb2664a004c8 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.rule.index;
 import com.google.common.collect.Iterators;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
@@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 public class RuleIndexerTest {
 
   @Rule
-  public EsTester esTester = new EsTester(new RuleIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingLoaderTest.java
new file mode 100644 (file)
index 0000000..5cc2a1c
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbTester;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.server.setting.DatabaseSettingLoader;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.data.MapEntry.entry;
+
+public class DatabaseSettingLoaderTest {
+
+  private static final String A_KEY = "a_key";
+
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+  private DatabaseSettingLoader underTest = new DatabaseSettingLoader(dbTester.getDbClient());
+
+  @Test
+  public void test_load() {
+    insertPropertyIntoDb(A_KEY, "foo");
+
+    assertThat(underTest.load(A_KEY)).isEqualTo("foo");
+    assertThat(underTest.load("missing")).isNull();
+  }
+
+  @Test
+  public void null_value_in_db_is_considered_as_empty_string() {
+    insertPropertyIntoDb(A_KEY, null);
+    assertThat(underTest.load(A_KEY)).isEqualTo("");
+  }
+
+  @Test
+  public void test_empty_value_in_db() {
+    insertPropertyIntoDb(A_KEY, "");
+    assertThat(underTest.load(A_KEY)).isEqualTo("");
+  }
+
+  @Test
+  public void test_loadAll_with_no_properties() {
+    ImmutableMap.Builder<String, String> map = ImmutableMap.builder();
+    underTest.loadAll(map);
+   assertThat(map.build().isEmpty()).isTrue();
+  }
+
+ @Test
+ public void test_loadAll() {
+  insertPropertyIntoDb("foo", "1");
+  insertPropertyIntoDb("bar", "2");
+  ImmutableMap.Builder<String, String> map = ImmutableMap.builder();
+  underTest.loadAll(map);
+  assertThat(map.build()).containsOnly(entry("foo", "1"), entry("bar", "2"));
+ }
+
+  private void insertPropertyIntoDb(String key, String value) {
+    dbTester.getDbClient().propertiesDao().insertProperty(new PropertyDto().setKey(key).setValue(value));
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingsEnablerTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/DatabaseSettingsEnablerTest.java
new file mode 100644 (file)
index 0000000..cbb01d0
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.server.setting.DatabaseSettingLoader;
+import org.sonar.server.setting.DatabaseSettingsEnabler;
+import org.sonar.server.setting.ThreadLocalSettings;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class DatabaseSettingsEnablerTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private ThreadLocalSettings settings = mock(ThreadLocalSettings.class);
+  private DatabaseSettingLoader loader = mock(DatabaseSettingLoader.class);
+  private DatabaseSettingsEnabler underTest = new DatabaseSettingsEnabler(settings, loader);
+
+  @After
+  public void tearDown() {
+    underTest.stop();
+  }
+
+  @Test
+  public void change_loader_at_startup() {
+    underTest.start();
+
+    verify(settings).setSettingLoader(loader);
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/NopSettingLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/NopSettingLoaderTest.java
new file mode 100644 (file)
index 0000000..6d4fd47
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.collect.ImmutableMap;
+import org.junit.Test;
+import org.sonar.server.setting.NopSettingLoader;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class NopSettingLoaderTest {
+
+  private NopSettingLoader underTest = new NopSettingLoader();
+
+  @Test
+  public void do_nothing() {
+    assertThat(underTest.load("foo")).isNull();
+
+    ImmutableMap.Builder<String,String> map = ImmutableMap.builder();
+    underTest.loadAll(map);
+    assertThat(map.build()).isEmpty();
+  }
+}
index 0724455f957474e5f7de95af8a008cae9605b838..2ce339ded1c69cd171519160531f3cd6b5c8443e 100644 (file)
 package org.sonar.server.setting;
 
 import org.junit.Test;
+import org.mockito.Mockito;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
-import org.sonar.db.property.PropertiesDao;
+import org.sonar.ce.settings.ProjectSettingsFactory;
+import org.sonar.db.DbClient;
 import org.sonar.db.property.PropertyDto;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -33,10 +36,10 @@ public class ProjectSettingsFactoryTest {
 
   static final String PROJECT_KEY = "PROJECT_KEY";
 
-  Settings settings = new Settings();
-  PropertiesDao dao = mock(PropertiesDao.class);
+  Settings settings = new MapSettings();
+  DbClient dbClient = mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS);
 
-  ProjectSettingsFactory underTest = new ProjectSettingsFactory(settings, dao);
+  ProjectSettingsFactory underTest = new ProjectSettingsFactory(settings, dbClient);
 
   @Test
   public void return_global_settings() {
@@ -49,7 +52,7 @@ public class ProjectSettingsFactoryTest {
 
   @Test
   public void return_project_settings() {
-    when(dao.selectProjectProperties(PROJECT_KEY)).thenReturn(newArrayList(
+    when(dbClient.propertiesDao().selectProjectProperties(PROJECT_KEY)).thenReturn(newArrayList(
       new PropertyDto().setKey("1").setValue("val1"),
       new PropertyDto().setKey("2").setValue("val2"),
       new PropertyDto().setKey("3").setValue("val3"))
@@ -65,7 +68,7 @@ public class ProjectSettingsFactoryTest {
   @Test
   public void project_settings_override_global_settings() {
     settings.setProperty("key", "value");
-    when(dao.selectProjectProperties(PROJECT_KEY)).thenReturn(newArrayList(
+    when(dbClient.propertiesDao().selectProjectProperties(PROJECT_KEY)).thenReturn(newArrayList(
         new PropertyDto().setKey("key").setValue("value2"))
     );
 
diff --git a/server/sonar-server/src/test/java/org/sonar/server/setting/ThreadLocalSettingsTest.java b/server/sonar-server/src/test/java/org/sonar/server/setting/ThreadLocalSettingsTest.java
new file mode 100644 (file)
index 0000000..4fdd484
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.setting;
+
+import com.google.common.collect.ImmutableMap;
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import javax.annotation.Nullable;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.config.PropertyDefinitions;
+
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.data.MapEntry.entry;
+import static org.mockito.Mockito.mock;
+
+public class ThreadLocalSettingsTest {
+
+  private static final String A_KEY = "a_key";
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private MapSettingLoader dbSettingLoader = new MapSettingLoader();
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  private ThreadLocalSettings underTest = null;
+
+  @After
+  public void tearDown() {
+    if (underTest != null) {
+      underTest.unload();
+    }
+  }
+
+  @Test
+  public void can_not_add_property_if_no_cache() {
+    underTest = create(Collections.emptyMap());
+
+    underTest.set("foo", "wiz");
+
+    assertThat(underTest.get("foo")).isNotPresent();
+  }
+
+  @Test
+  public void can_not_remove_system_property_if_no_cache() {
+    underTest = create(ImmutableMap.of("foo", "bar"));
+
+    underTest.remove("foo");
+
+    assertThat(underTest.get("foo").get()).isEqualTo("bar");
+  }
+
+  @Test
+  public void add_property_to_cache() {
+    underTest = create(Collections.emptyMap());
+
+    underTest.load();
+    underTest.set("foo", "bar");
+    assertThat(underTest.get("foo").get()).isEqualTo("bar");
+    underTest.unload();
+
+    // no more cache
+    assertThat(underTest.get("foo")).isNotPresent();
+  }
+
+  @Test
+  public void remove_property_from_cache() {
+    underTest = create(Collections.emptyMap());
+
+    underTest.load();
+    underTest.set("foo", "bar");
+    assertThat(underTest.get("foo").get()).isEqualTo("bar");
+    underTest.remove("foo");
+    assertThat(underTest.get("foo")).isNotPresent();
+    underTest.unload();
+
+    // no more cache
+    assertThat(underTest.get("foo")).isNotPresent();
+  }
+
+  @Test
+  public void load_encryption_secret_key_from_system_properties() throws Exception {
+    File secretKey = temp.newFile();
+
+    underTest = create(ImmutableMap.of("foo", "bar", "sonar.secretKeyPath", secretKey.getAbsolutePath()));
+
+    assertThat(underTest.getEncryption().hasSecretKey()).isTrue();
+  }
+
+  @Test
+  public void encryption_secret_key_is_undefined_by_default() {
+    underTest = create(ImmutableMap.of("foo", "bar"));
+
+    assertThat(underTest.getEncryption().hasSecretKey()).isFalse();
+  }
+
+  private ThreadLocalSettings create(Map<String, String> systemProps) {
+    Properties p = new Properties();
+    p.putAll(systemProps);
+    return new ThreadLocalSettings(new PropertyDefinitions(), p, dbSettingLoader);
+  }
+
+  @Test
+  public void load_system_properties() {
+    underTest = create(ImmutableMap.of("foo", "1", "bar", "2"));
+
+    assertThat(underTest.get("foo").get()).isEqualTo("1");
+    assertThat(underTest.get("missing")).isNotPresent();
+    assertThat(underTest.getProperties()).containsOnly(entry("foo", "1"), entry("bar", "2"));
+  }
+
+  @Test
+  public void database_properties_are_not_cached_by_default() {
+    insertPropertyIntoDb("foo", "from db");
+    underTest = create(Collections.emptyMap());
+
+    assertThat(underTest.get("foo").get()).isEqualTo("from db");
+
+    deletePropertyFromDb("foo");
+    // no cache, change is visible immediately
+    assertThat(underTest.get("foo")).isNotPresent();
+  }
+
+  @Test
+  public void system_settings_have_precedence_over_database() {
+    insertPropertyIntoDb("foo", "from db");
+    underTest = create(ImmutableMap.of("foo", "from system"));
+
+    assertThat(underTest.get("foo").get()).isEqualTo("from system");
+  }
+
+  @Test
+  public void getProperties_are_all_properties_with_value() {
+    insertPropertyIntoDb("db", "from db");
+    insertPropertyIntoDb("empty", "");
+    underTest = create(ImmutableMap.of("system", "from system"));
+
+    assertThat(underTest.getProperties()).containsOnly(entry("system", "from system"), entry("db", "from db"), entry("empty", ""));
+  }
+
+  @Test
+  public void load_creates_a_thread_specific_cache() throws InterruptedException {
+    insertPropertyIntoDb(A_KEY, "v1");
+
+    underTest = create(Collections.emptyMap());
+    underTest.load();
+
+    assertThat(underTest.get(A_KEY).get()).isEqualTo("v1");
+
+    deletePropertyFromDb(A_KEY);
+    // the main thread still has "v1" in cache, but not new thread
+    assertThat(underTest.get(A_KEY).get()).isEqualTo("v1");
+    verifyValueInNewThread(underTest, null);
+
+    insertPropertyIntoDb(A_KEY, "v2");
+    // the main thread still has the old value "v1" in cache, but new thread loads "v2"
+    assertThat(underTest.get(A_KEY).get()).isEqualTo("v1");
+    verifyValueInNewThread(underTest, "v2");
+
+    underTest.unload();
+  }
+
+  @Test
+  public void load_throws_ISE_if_load_called_twice_without_unload_in_between() {
+    underTest = create(Collections.emptyMap());
+    underTest.load();
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("load called twice for thread '" + Thread.currentThread().getName()
+      + "' or state wasn't cleared last time it was used");
+
+    underTest.load();
+  }
+
+  @Test
+  public void keep_in_thread_cache_the_fact_that_a_property_is_not_in_db() {
+    underTest = create(Collections.emptyMap());
+    underTest.load();
+    assertThat(underTest.get(A_KEY)).isNotPresent();
+
+    insertPropertyIntoDb(A_KEY, "bar");
+    // do not execute new SQL request, cache contains the information of missing property
+    assertThat(underTest.get(A_KEY)).isNotPresent();
+
+    underTest.unload();
+  }
+
+  @Test
+  public void change_setting_loader() {
+    underTest = new ThreadLocalSettings(new PropertyDefinitions(), new Properties());
+
+    assertThat(underTest.getSettingLoader()).isNotNull();
+
+    SettingLoader newLoader = mock(SettingLoader.class);
+    underTest.setSettingLoader(newLoader);
+    assertThat(underTest.getSettingLoader()).isSameAs(newLoader);
+  }
+
+  @Test
+  public void cache_db_calls_if_property_is_not_persisted() {
+    underTest = create(Collections.emptyMap());
+    underTest.load();
+    assertThat(underTest.get(A_KEY)).isNotPresent();
+    assertThat(underTest.get(A_KEY)).isNotPresent();
+    underTest.unload();
+  }
+
+  private void insertPropertyIntoDb(String key, @Nullable String value) {
+    dbSettingLoader.put(key, value);
+  }
+
+  private void deletePropertyFromDb(String key) {
+    dbSettingLoader.remove(key);
+  }
+
+  private void verifyValueInNewThread(ThreadLocalSettings settings, @Nullable String expectedValue) throws InterruptedException {
+    CacheCaptorThread captor = new CacheCaptorThread();
+    captor.verifyValue(settings, expectedValue);
+  }
+
+  private class CacheCaptorThread extends Thread {
+    private final CountDownLatch latch = new CountDownLatch(1);
+    private ThreadLocalSettings settings;
+    private String value;
+
+    void verifyValue(ThreadLocalSettings settings, @Nullable String expectedValue) throws InterruptedException {
+      this.settings = settings;
+      this.start();
+      this.latch.await(5, SECONDS);
+      assertThat(value).isEqualTo(expectedValue);
+    }
+
+    @Override
+    public void run() {
+      try {
+        settings.load();
+        value = settings.get(A_KEY).orElse(null);
+        latch.countDown();
+      } finally {
+        settings.unload();
+      }
+    }
+  }
+
+  private static class MapSettingLoader implements SettingLoader {
+    private final Map<String, String> map = new HashMap<>();
+
+    public MapSettingLoader put(String key, String value) {
+      map.put(key, value);
+      return this;
+    }
+
+    public MapSettingLoader remove(String key) {
+      map.remove(key);
+      return this;
+    }
+
+    @Override
+    public String load(String key) {
+      return map.get(key);
+    }
+
+    @Override
+    public void loadAll(ImmutableMap.Builder<String, String> appendTo) {
+      appendTo.putAll(map);
+    }
+  }
+}
index fe866e201c14e6872d3e5332a63a2e8a815f29ab..85260daa9bf49cd4c5040cf3daea70c178a96c1b 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.startup;
 import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.LogTester;
@@ -54,7 +54,7 @@ public class ClearRulesOverloadedDebtTest {
   public DbTester tester = DbTester.create(system2);
 
   @Rule
-  public EsTester esTester = new EsTester(new RuleIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
 
   @Rule
   public LogTester logTester = new LogTester();
index 885beb133bf55a7d702eee135d4da76945827dac..34ee9c216f1844fc47976c904340728a150532f5 100644 (file)
@@ -23,7 +23,7 @@ import com.google.common.base.Optional;
 import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.es.SearchOptions;
 
@@ -33,7 +33,7 @@ import static org.assertj.guava.api.Assertions.assertThat;
 
 public class TestIndexTest {
   @Rule
-  public EsTester es = new EsTester(new TestIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new TestIndexDefinition(new MapSettings()));
 
   TestIndex underTest = new TestIndex(es.client());
 
index 1cef3e8bd183cda56973e13aeb9a42b23f20af1c..00046be642ee7898a7b7bbc3ca4a51322fc950d1 100644 (file)
@@ -33,7 +33,7 @@ import org.elasticsearch.search.SearchHit;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
 import org.sonar.db.protobuf.DbFileSources;
@@ -59,7 +59,7 @@ import static org.sonar.server.test.index.TestIndexDefinition.TYPE;
 public class TestIndexerTest {
 
   @Rule
-  public EsTester es = new EsTester(new TestIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new TestIndexDefinition(new MapSettings()));
 
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
index 71c738b5a7af316df14df09fa29251cb4d2c9709..93632b73e8d6934da05b59e5b6dd1b1d11ad1e9b 100644 (file)
@@ -25,7 +25,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
@@ -45,7 +45,7 @@ import org.sonar.server.ws.WsTester;
 public class ListActionTest {
 
   @Rule
-  public EsTester es = new EsTester(new TestIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new TestIndexDefinition(new MapSettings()));
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
index 5a11245b9a0ff075d06544156d2a70e4e6626974..799eca8f0a1bc84eac89612e819e3378073ec9a6 100644 (file)
@@ -147,7 +147,7 @@ public class UserSessionRule implements TestRule, UserSession {
   protected void after() {
     this.currentUserSession = null;
     if (serverTester != null) {
-      serverTester.get(ThreadLocalUserSession.class).remove();
+      serverTester.get(ThreadLocalUserSession.class).unload();
     }
   }
 
index 63b80f430b65289d21768733df9a34eb40ffbb84..6a2cf972ade596f771737cad50d78c081f7e3998 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypeTree;
 import org.sonar.api.resources.ResourceTypes;
@@ -83,7 +84,7 @@ public class GlobalNavigationActionTest {
 
   @Test
   public void empty_call() throws Exception {
-    wsTester = new WsTester(new NavigationWs(new GlobalNavigationAction(activeDashboardDao, new Views(userSessionRule), new Settings(), new ResourceTypes(), userSessionRule)));
+    wsTester = new WsTester(new NavigationWs(new GlobalNavigationAction(activeDashboardDao, new Views(userSessionRule), new MapSettings(), new ResourceTypes(), userSessionRule)));
 
     wsTester.newGetRequest("api/navigation", "global").execute().assertJson(getClass(), "empty.json");
   }
@@ -103,7 +104,7 @@ public class GlobalNavigationActionTest {
           .addRelations("PAL", "LAP")
           .build()
       });
-    wsTester = new WsTester(new NavigationWs(new GlobalNavigationAction(activeDashboardDao, new Views(userSessionRule), new Settings(), resourceTypes, userSessionRule)));
+    wsTester = new WsTester(new NavigationWs(new GlobalNavigationAction(activeDashboardDao, new Views(userSessionRule), new MapSettings(), resourceTypes, userSessionRule)));
 
     wsTester.newGetRequest("api/navigation", "global").execute().assertJson(getClass(), "with_qualifiers.json");
   }
@@ -111,7 +112,7 @@ public class GlobalNavigationActionTest {
   @Test
   public void only_logo() throws Exception {
     wsTester = new WsTester(new NavigationWs(new GlobalNavigationAction(activeDashboardDao, new Views(userSessionRule),
-      new Settings()
+      new MapSettings()
         .setProperty("sonar.lf.logoUrl", "http://some-server.tld/logo.png")
         .setProperty("sonar.lf.logoWidthPx", "123"),
       new ResourceTypes(), userSessionRule)));
@@ -159,7 +160,7 @@ public class GlobalNavigationActionTest {
 
     session.commit();
 
-    Settings settings = new Settings()
+    Settings settings = new MapSettings()
       .setProperty("sonar.lf.logoUrl", "http://some-server.tld/logo.png")
       .setProperty("sonar.lf.logoWidthPx", "123");
     wsTester = new WsTester(new NavigationWs(new GlobalNavigationAction(activeDashboardDao, createViews(), settings, new ResourceTypes(), userSessionRule)));
index c3f262889a439dd3ac352dd7e39494238b6e589f..49086c475e504268c7b641ea908f768f60d618f7 100644 (file)
@@ -26,6 +26,7 @@ import org.junit.Test;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.web.NavigationSection;
 import org.sonar.api.web.Page;
@@ -53,7 +54,7 @@ public class SettingsNavigationActionTest {
 
   @Before
   public void before() {
-    settings = new Settings();
+    settings = new MapSettings();
     i18n = mock(I18n.class);
     when(i18n.message(any(Locale.class), anyString(), anyString())).thenAnswer(new Answer<String>() {
       @Override
index e6bd4e5843f45b17c14813a63403cd68c2687ba9..7f5c72ae4d7144015410491214f3c7eb03c22990 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.user;
 
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.config.Settings;
 import org.sonar.api.security.LoginPasswordAuthenticator;
 import org.sonar.api.security.SecurityRealm;
@@ -33,7 +34,7 @@ import static org.mockito.Mockito.verify;
 
 public class SecurityRealmFactoryTest {
 
-  Settings settings = new Settings();
+  private Settings settings = new MapSettings();
 
   /**
    * Typical usage.
@@ -43,7 +44,7 @@ public class SecurityRealmFactoryTest {
     SecurityRealm realm = spy(new FakeRealm());
     settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
 
-    SecurityRealmFactory factory = new SecurityRealmFactory(settings, new SecurityRealm[]{realm});
+    SecurityRealmFactory factory = new SecurityRealmFactory(settings, new SecurityRealm[] {realm});
     factory.start();
     assertThat(factory.getRealm()).isSameAs(realm);
     assertThat(factory.hasExternalAuthentication()).isTrue();
@@ -77,7 +78,7 @@ public class SecurityRealmFactoryTest {
     settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
     LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
 
-    SecurityRealmFactory factory = new SecurityRealmFactory(settings, new LoginPasswordAuthenticator[]{authenticator});
+    SecurityRealmFactory factory = new SecurityRealmFactory(settings, new LoginPasswordAuthenticator[] {authenticator});
     SecurityRealm realm = factory.getRealm();
     assertThat(realm).isInstanceOf(CompatibilityRealm.class);
   }
@@ -89,8 +90,8 @@ public class SecurityRealmFactoryTest {
     LoginPasswordAuthenticator authenticator = new FakeAuthenticator();
     settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_CLASS, FakeAuthenticator.class.getName());
 
-    SecurityRealmFactory factory = new SecurityRealmFactory(settings, new SecurityRealm[]{realm},
-      new LoginPasswordAuthenticator[]{authenticator});
+    SecurityRealmFactory factory = new SecurityRealmFactory(settings, new SecurityRealm[] {realm},
+      new LoginPasswordAuthenticator[] {authenticator});
     assertThat(factory.getRealm()).isSameAs(realm);
   }
 
@@ -112,7 +113,7 @@ public class SecurityRealmFactoryTest {
     settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
     settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_IGNORE_STARTUP_FAILURE, true);
 
-    new SecurityRealmFactory(settings, new SecurityRealm[]{realm}).start();
+    new SecurityRealmFactory(settings, new SecurityRealm[] {realm}).start();
     verify(realm).init();
   }
 
@@ -122,7 +123,7 @@ public class SecurityRealmFactoryTest {
     settings.setProperty(CoreProperties.CORE_AUTHENTICATOR_REALM, realm.getName());
 
     try {
-      new SecurityRealmFactory(settings, new SecurityRealm[]{realm}).start();
+      new SecurityRealmFactory(settings, new SecurityRealm[] {realm}).start();
       fail();
     } catch (SonarException e) {
       assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
index 8968b31b604f4bb96f42afaee2ef0cb7a2e53990..e9e39034514ac2648e85b0b44a9806c9814d111e 100644 (file)
@@ -19,8 +19,6 @@
  */
 package org.sonar.server.user;
 
-import static org.assertj.core.api.Assertions.assertThat;
-
 import java.util.Locale;
 import org.junit.After;
 import org.junit.Before;
@@ -31,6 +29,8 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.AnonymousMockUserSession;
 import org.sonar.server.tester.MockUserSession;
 
+import static org.assertj.core.api.Assertions.assertThat;
+
 public class ThreadLocalUserSessionTest {
 
   ThreadLocalUserSession threadLocalUserSession = new ThreadLocalUserSession();
@@ -41,13 +41,13 @@ public class ThreadLocalUserSessionTest {
   @Before
   public void setUp() {
     // for test isolation
-    threadLocalUserSession.remove();
+    threadLocalUserSession.unload();
   }
 
   @After
   public void tearDown() {
     // clean up for next test
-    threadLocalUserSession.remove();
+    threadLocalUserSession.unload();
   }
 
   @Test
index 55e0b0cda3d165c2abe8df8f0d0c99d3cd58b044..6e6810a596a9c7b3fc979b0640c7608d4f54269e 100644 (file)
@@ -27,9 +27,10 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.junit.Before;
 import org.junit.Test;
-import org.sonar.core.platform.ComponentContainer;
+import org.mockito.Mockito;
 import org.sonar.server.authentication.UserSessionInitializer;
 import org.sonar.server.platform.Platform;
+import org.sonar.server.setting.ThreadLocalSettings;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -40,45 +41,44 @@ import static org.mockito.Mockito.when;
 public class UserSessionFilterTest {
 
   private UserSessionInitializer userSessionInitializer = mock(UserSessionInitializer.class);
-  private Platform platform = mock(Platform.class);
-  private ComponentContainer componentContainer = mock(ComponentContainer.class);
+  private Platform platform = mock(Platform.class, Mockito.RETURNS_DEEP_STUBS);
   private HttpServletRequest request = mock(HttpServletRequest.class);
   private HttpServletResponse response = mock(HttpServletResponse.class);
   private FilterChain chain = mock(FilterChain.class);
-
+  private ThreadLocalSettings settings = mock(ThreadLocalSettings.class);
   private UserSessionFilter underTest = new UserSessionFilter(platform);
 
   @Before
   public void setUp() {
-    when(platform.getContainer()).thenReturn(componentContainer);
+    when(platform.getContainer().getComponentByType(ThreadLocalSettings.class)).thenReturn(settings);
   }
 
   @Test
   public void cleanup_user_session_after_request_handling() throws IOException, ServletException {
-    when(componentContainer.getComponentByType(UserSessionInitializer.class)).thenReturn(userSessionInitializer);
+    when(platform.getContainer().getComponentByType(UserSessionInitializer.class)).thenReturn(userSessionInitializer);
     when(userSessionInitializer.initUserSession(request, response)).thenReturn(true);
 
     underTest.doFilter(request, response, chain);
 
     verify(chain).doFilter(request, response);
     verify(userSessionInitializer).initUserSession(request, response);
-    verify(userSessionInitializer).removeUserSession();
   }
 
   @Test
   public void stop_when_user_session_return_false() throws Exception {
-    when(componentContainer.getComponentByType(UserSessionInitializer.class)).thenReturn(userSessionInitializer);
+    when(platform.getContainer().getComponentByType(UserSessionInitializer.class)).thenReturn(userSessionInitializer);
     when(userSessionInitializer.initUserSession(request, response)).thenReturn(false);
 
     underTest.doFilter(request, response, chain);
 
     verify(chain, never()).doFilter(request, response);
     verify(userSessionInitializer).initUserSession(request, response);
-    verify(userSessionInitializer).removeUserSession();
   }
 
   @Test
   public void does_nothing_when_not_initialized() throws Exception {
+    when(platform.getContainer().getComponentByType(UserSessionInitializer.class)).thenReturn(null);
+
     underTest.doFilter(request, response, chain);
 
     verify(chain).doFilter(request, response);
index 2820f85d3f7af0312981c5970c44a2a67c5fe2eb..cce9baabd2b9817bd04793a44a33fe2dd52c1534 100644 (file)
  */
 package org.sonar.server.user;
 
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.data.MapEntry.entry;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.sonar.api.CoreProperties.CORE_DEFAULT_GROUP;
-import static org.sonar.db.user.UserTesting.newDisabledUser;
-import static org.sonar.db.user.UserTesting.newUserDto;
-
 import com.google.common.base.Strings;
 import java.util.List;
 import org.elasticsearch.search.SearchHit;
@@ -38,6 +27,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.platform.NewUserHandler;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
@@ -57,6 +47,17 @@ import org.sonar.server.user.index.UserIndexDefinition;
 import org.sonar.server.user.index.UserIndexer;
 import org.sonar.server.util.Validation;
 
+import static com.google.common.collect.Lists.newArrayList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.data.MapEntry.entry;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.sonar.api.CoreProperties.CORE_DEFAULT_GROUP;
+import static org.sonar.db.user.UserTesting.newDisabledUser;
+import static org.sonar.db.user.UserTesting.newUserDto;
+
 public class UserUpdaterTest {
 
   static final long NOW = 1418215735482L;
@@ -65,7 +66,7 @@ public class UserUpdaterTest {
   static final String DEFAULT_LOGIN = "marius";
 
   @Rule
-  public EsTester es = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester es = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   System2 system2 = mock(System2.class);
 
@@ -78,7 +79,7 @@ public class UserUpdaterTest {
 
   ArgumentCaptor<NewUserHandler.Context> newUserHandler = ArgumentCaptor.forClass(NewUserHandler.Context.class);
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   UserDao userDao = dbClient.userDao();
   GroupDao groupDao = dbClient.groupDao();
   GroupMembershipFinder groupMembershipFinder = new GroupMembershipFinder(userDao, dbClient.groupMembershipDao());
index 4779f300701c910bb1ef4189bf949d95129c116d..d50fc0ce5520b045666fd31f75f648ea544708a3 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.user.index;
 
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.NewIndex;
 
@@ -32,7 +32,7 @@ public class UserIndexDefinitionTest {
 
   @Test
   public void define() {
-    UserIndexDefinition def = new UserIndexDefinition(new Settings());
+    UserIndexDefinition def = new UserIndexDefinition(new MapSettings());
     def.define(underTest);
 
     assertThat(underTest.getIndices()).hasSize(1);
index 6d542314170be499a09132f94bb08b32c957d497..daca9c475ee4e45ba2717ce066ed2d8da6696f7d 100644 (file)
@@ -26,7 +26,7 @@ import java.util.Locale;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.es.SearchOptions;
 
@@ -43,7 +43,7 @@ public class UserIndexTest {
   private static final long DATE_2 = 1_500_000_000_001L;
 
   @Rule
-  public EsTester esTester = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   private UserIndex index;
 
index 83130df526d5f5eace7db6be57c08a216a9cdf10..68f746ed4fee68634d535ac612e68a692e5c47e6 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.user.index;
 import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
@@ -36,7 +36,7 @@ public class UserIndexerTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester esTester = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   @Test
   public void index_nothing() {
index 6e5611fb4ee155b269f73e85caec83511bb5cf53..0b14e34a80d8fd0d20ae6dbf423779e6a1ba31f0 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.core.permission.GlobalPermissions;
@@ -56,7 +57,7 @@ import static org.mockito.Mockito.when;
 
 public class ChangePasswordActionTest {
 
-  static final Settings settings = new Settings().setProperty("sonar.defaultGroup", "sonar-users");
+  static final Settings settings = new MapSettings().setProperty("sonar.defaultGroup", "sonar-users");
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
index 57b3a94197f711e5a6bfce7012fb4a7cb39a6771..8f338ebb33ac55a99d7902af990e02d2c73f9ba0 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.i18n.I18n;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
@@ -54,7 +55,7 @@ import static org.mockito.Mockito.when;
 
 public class CreateActionTest {
 
-  private static final Settings settings = new Settings().setProperty("sonar.defaultGroup", "sonar-users");
+  private static final Settings settings = new MapSettings().setProperty("sonar.defaultGroup", "sonar-users");
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
index 37a743a25cca0509625698a9eb0256978c8c073b..c1f5e3d45042b72b62929203f8d0418b01e2cad2 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.core.permission.GlobalPermissions;
@@ -52,7 +53,7 @@ import static org.sonar.db.user.UserTokenTesting.newUserToken;
 
 public class DeactivateActionTest {
 
-  static final Settings settings = new Settings();
+  static final Settings settings = new MapSettings();
 
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
index bb72587def83212bc88156e6e1cec3236627f0b7..7f7eb7fffabfeb82928ea68b5dab054c6bd036bd 100644 (file)
@@ -21,11 +21,9 @@ package org.sonar.server.user.ws;
 
 import com.google.common.collect.Lists;
 import java.util.List;
-import org.junit.Before;
-import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.api.utils.System2;
 import org.sonar.core.permission.GlobalPermissions;
@@ -58,7 +56,7 @@ import static org.sonar.test.JsonAssert.assertJson;
 public class SearchActionTest {
 
   @Rule
-  public EsTester esTester = new EsTester(new UserIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new UserIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone();
index 26afff94651f8d6fc6f4ab3724104492da256102..f6ffb4c2fcdd316453eae095e5f01edc2e5751c3 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
 import org.sonar.core.permission.GlobalPermissions;
@@ -48,7 +49,7 @@ import static org.mockito.Mockito.mock;
 
 public class UpdateActionTest {
 
-  static final Settings settings = new Settings().setProperty("sonar.defaultGroup", "sonar-users");
+  static final Settings settings = new MapSettings().setProperty("sonar.defaultGroup", "sonar-users");
 
   System2 system2 = new System2();
 
index a7e864eac058d3f61f0596e22d9f7f88ee6a9fc8..7a05a906b7e864c034a9e7416f7d1bae4745fc8f 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.permission.GlobalPermissions;
@@ -72,7 +73,7 @@ public class DeleteActionTest {
     permissionTemplateDao = dbClient.permissionTemplateDao();
     dbSession = db.getSession();
 
-    Settings settings = new Settings().setProperty(CoreProperties.CORE_DEFAULT_GROUP, CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE);
+    Settings settings = new MapSettings().setProperty(CoreProperties.CORE_DEFAULT_GROUP, CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE);
     GroupDto defaultGroup = groupDao.insert(dbSession, new GroupDto().setName(CoreProperties.CORE_DEFAULT_GROUP_DEFAULT_VALUE));
     defaultGroupId = defaultGroup.getId();
     dbSession.commit();
index 0df1c0d56a9398863471297eb5c48eeeb55e9c85..34db1eac5191eb55ae3e4016e0dee96d839e1967 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.view.index;
 
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.NewIndex;
 
@@ -32,7 +32,7 @@ public class ViewIndexDefinitionTest {
 
   @Test
   public void define() {
-    ViewIndexDefinition def = new ViewIndexDefinition(new Settings());
+    ViewIndexDefinition def = new ViewIndexDefinition(new MapSettings());
     def.define(underTest);
 
     assertThat(underTest.getIndices()).hasSize(1);
index 4f0210e6b95c020127b911a99d19ddc1955664c8..20cccf614ce547b1a2093351b9a7334d1938ee07 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.view.index;
 import java.util.List;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.server.es.EsTester;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -34,7 +34,7 @@ import static org.sonar.server.view.index.ViewIndexDefinition.TYPE_VIEW;
 public class ViewIndexTest {
 
   @Rule
-  public EsTester esTester = new EsTester(new ViewIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new ViewIndexDefinition(new MapSettings()));
 
   ViewIndex index = new ViewIndex(esTester.client());
 
index 11e30bec4766cc82ac97252aecfd42f1fd6aab41..dba33b0e442e2b00b3a09d99bd7f3481a02f056d 100644 (file)
@@ -25,7 +25,7 @@ import java.util.List;
 import java.util.Map;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbClient;
@@ -59,7 +59,7 @@ public class ViewIndexerTest {
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
 
   @Rule
-  public EsTester esTester = new EsTester(new IssueIndexDefinition(new Settings()), new ViewIndexDefinition(new Settings()));
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings()), new ViewIndexDefinition(new MapSettings()));
 
   @Rule
   public UserSessionRule userSessionRule = UserSessionRule.standalone();
index 67867b40f7f7cf7f83df1d9c3bc5b047c231b794..e4abf894bf78b858abc2a6d34d4eb8dd767bf2d3 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.i18n.I18n;
 
 import static org.mockito.Matchers.anyString;
@@ -50,7 +51,7 @@ public class PeriodsTest {
   static int PERIOD_INDEX = 1;
   @Rule
   public ExpectedException thrown = ExpectedException.none();
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   I18n i18n = mock(I18n.class);
   Periods periods = new Periods(settings, i18n);
 
index f9296bcd139c8a0037d33cb7088699edd27b6f3a..60884967562ae017830aa4a88c630a74c308469c 100644 (file)
@@ -52,6 +52,7 @@ import org.simpleframework.http.Response;
 import org.simpleframework.http.core.Container;
 import org.simpleframework.transport.connect.SocketConnection;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.platform.Server;
 import org.sonar.api.utils.SonarException;
 
@@ -146,31 +147,31 @@ public class DefaultHttpDownloaderTest {
       public void describeTo(Description arg0) {
       }
     });
-    DefaultHttpDownloader downloader = new DefaultHttpDownloader(new Settings(), 10, 50000);
+    DefaultHttpDownloader downloader = new DefaultHttpDownloader(new MapSettings(), 10, 50000);
     downloader.openStream(new URI(url));
   }
 
   @Test
   public void downloadBytes() throws URISyntaxException {
-    byte[] bytes = new DefaultHttpDownloader(new Settings()).readBytes(new URI(baseUrl));
+    byte[] bytes = new DefaultHttpDownloader(new MapSettings()).readBytes(new URI(baseUrl));
     assertThat(bytes.length).isGreaterThan(10);
   }
 
   @Test
   public void readString() throws URISyntaxException {
-    String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl), StandardCharsets.UTF_8);
+    String text = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl), StandardCharsets.UTF_8);
     assertThat(text.length()).isGreaterThan(10);
   }
 
   @Test
   public void readGzipString() throws URISyntaxException {
-    String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/gzip/"), StandardCharsets.UTF_8);
+    String text = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl + "/gzip/"), StandardCharsets.UTF_8);
     assertThat(text).isEqualTo("GZIP response");
   }
 
   @Test
   public void readStringWithDefaultTimeout() throws URISyntaxException {
-    String text = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8);
+    String text = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8);
     assertThat(text.length()).isGreaterThan(10);
   }
 
@@ -186,7 +187,7 @@ public class DefaultHttpDownloaderTest {
       public void describeTo(Description arg0) {
       }
     });
-    new DefaultHttpDownloader(new Settings(), 50).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8);
+    new DefaultHttpDownloader(new MapSettings(), 50).readString(new URI(baseUrl + "/timeout/"), StandardCharsets.UTF_8);
   }
 
   @Test
@@ -194,7 +195,7 @@ public class DefaultHttpDownloaderTest {
     File toDir = temporaryFolder.newFolder();
     File toFile = new File(toDir, "downloadToFile.txt");
 
-    new DefaultHttpDownloader(new Settings()).download(new URI(baseUrl), toFile);
+    new DefaultHttpDownloader(new MapSettings()).download(new URI(baseUrl), toFile);
     assertThat(toFile).exists();
     assertThat(toFile.length()).isGreaterThan(10l);
   }
@@ -206,7 +207,7 @@ public class DefaultHttpDownloaderTest {
 
     try {
       int port = new InetSocketAddress("localhost", 0).getPort();
-      new DefaultHttpDownloader(new Settings()).download(new URI("http://localhost:" + port), toFile);
+      new DefaultHttpDownloader(new MapSettings()).download(new URI("http://localhost:" + port), toFile);
     } catch (SonarException e) {
       assertThat(toFile).doesNotExist();
     }
@@ -217,7 +218,7 @@ public class DefaultHttpDownloaderTest {
     Server server = mock(Server.class);
     when(server.getVersion()).thenReturn("2.2");
 
-    InputStream stream = new DefaultHttpDownloader(server, new Settings()).openStream(new URI(baseUrl));
+    InputStream stream = new DefaultHttpDownloader(server, new MapSettings()).openStream(new URI(baseUrl));
     Properties props = new Properties();
     props.load(stream);
     stream.close();
@@ -227,7 +228,7 @@ public class DefaultHttpDownloaderTest {
 
   @Test
   public void followRedirect() throws URISyntaxException {
-    String content = new DefaultHttpDownloader(new Settings()).readString(new URI(baseUrl + "/redirect/"), StandardCharsets.UTF_8);
+    String content = new DefaultHttpDownloader(new MapSettings()).readString(new URI(baseUrl + "/redirect/"), StandardCharsets.UTF_8);
     assertThat(content).contains("agent");
   }
 
@@ -247,19 +248,19 @@ public class DefaultHttpDownloaderTest {
 
   @Test
   public void supported_schemes() {
-    assertThat(new DefaultHttpDownloader(new Settings()).getSupportedSchemes()).contains("http");
+    assertThat(new DefaultHttpDownloader(new MapSettings()).getSupportedSchemes()).contains("http");
   }
 
   @Test
   public void uri_description() throws URISyntaxException {
-    String description = new DefaultHttpDownloader(new Settings()).description(new URI("http://sonarsource.org"));
+    String description = new DefaultHttpDownloader(new MapSettings()).description(new URI("http://sonarsource.org"));
     assertThat(description).matches("http://sonarsource.org \\(.*\\)");
   }
 
   @Test
   public void configure_http_and_https_proxies() {
     DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class);
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("http.proxyHost", "1.2.3.4");
     settings.setProperty("http.proxyPort", "80");
     settings.setProperty("https.proxyHost", "5.6.7.8");
@@ -277,7 +278,7 @@ public class DefaultHttpDownloaderTest {
   @Test
   public void https_defaults_are_http_properties() {
     DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class);
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("http.proxyHost", "1.2.3.4");
     settings.setProperty("http.proxyPort", "80");
 
@@ -292,7 +293,7 @@ public class DefaultHttpDownloaderTest {
   @Test
   public void configure_http_proxy_credentials() {
     DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class);
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("https.proxyHost", "1.2.3.4");
     settings.setProperty("http.proxyUser", "the_login");
     settings.setProperty("http.proxyPassword", "the_passwd");
@@ -317,7 +318,7 @@ public class DefaultHttpDownloaderTest {
   @Test
   public void no_http_proxy_settings_by_default() {
     DefaultHttpDownloader.SystemFacade system = mock(DefaultHttpDownloader.SystemFacade.class);
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     new DefaultHttpDownloader.BaseHttpDownloader(system, settings, null);
 
     verify(system, never()).setProperty(eq("http.proxyHost"), anyString());
index 0b564f115dfa350d7a0a8be5a8a9a8c786aa6c26..2ab4bbad1828c5184ff20c806d0955467c715607 100644 (file)
@@ -23,6 +23,7 @@ import java.util.Properties;
 import org.apache.commons.dbcp.BasicDataSource;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.db.dialect.PostgreSql;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -31,7 +32,7 @@ public class DefaultDatabaseTest {
 
   @Test
   public void shouldLoadDefaultValues() {
-    DefaultDatabase db = new DefaultDatabase(new Settings());
+    DefaultDatabase db = new DefaultDatabase(new MapSettings());
     db.initSettings();
 
     Properties props = db.getProperties();
@@ -56,7 +57,7 @@ public class DefaultDatabaseTest {
 
   @Test
   public void shouldCompleteProperties() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
 
     DefaultDatabase db = new DefaultDatabase(settings) {
       @Override
@@ -73,7 +74,7 @@ public class DefaultDatabaseTest {
 
   @Test
   public void shouldStart() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("sonar.jdbc.url", "jdbc:h2:mem:sonar");
     settings.setProperty("sonar.jdbc.driverClassName", "org.h2.Driver");
     settings.setProperty("sonar.jdbc.username", "sonar");
@@ -90,7 +91,7 @@ public class DefaultDatabaseTest {
 
   @Test
   public void shouldGuessDialectFromUrl() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("sonar.jdbc.url", "jdbc:postgresql://localhost/sonar");
 
     DefaultDatabase database = new DefaultDatabase(settings);
@@ -101,7 +102,7 @@ public class DefaultDatabaseTest {
 
   @Test
   public void shouldGuessDefaultDriver() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("sonar.jdbc.url", "jdbc:postgresql://localhost/sonar");
 
     DefaultDatabase database = new DefaultDatabase(settings);
index e4d2fd0aa0a4eeffcbbd966d3a2609cb35ceb806..4d008a2338cedb64341b777e667e3c92049bb663 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.db;
 
-import com.google.common.collect.Maps;
 import java.io.File;
 import java.io.InputStream;
 import java.net.HttpURLConnection;
@@ -38,6 +37,7 @@ import org.dbunit.IDatabaseTester;
 import org.dbunit.dataset.datatype.IDataTypeFactory;
 import org.junit.AssumptionViolatedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.db.dialect.H2;
@@ -74,7 +74,7 @@ class TestDb {
 
   private TestDb(@Nullable String schemaPath) {
     if (db == null) {
-      Settings settings = new Settings().setProperties(Maps.fromProperties(System.getProperties()));
+      Settings settings = new MapSettings().addProperties(System.getProperties());
       if (settings.hasKey("orchestrator.configUrl")) {
         loadOrchestratorSettings(settings);
       }
index f6f1e415f3707a75eb7288f523bc49d700b51d67..68a98b3d069d1cc4f62f5c09f9000c2a2bbcd1e3 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
@@ -63,7 +64,7 @@ public class PermissionRepositoryTest {
   DbClient dbClient = dbTester.getDbClient();
   DbSession session = dbTester.getSession();
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   PermissionRepository underTest = new PermissionRepository(dbTester.getDbClient(), settings);
 
   @Before
index e7f4ea58ed1146de6ec01aee55e1c73d655d483e..c3e4987ce75656adafb8a6a410a5f4947d3c0be4 100644 (file)
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.Date;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Scopes;
 import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
@@ -54,7 +55,7 @@ public class PurgeConfigurationTest {
 
   @Test
   public void do_not_delete_directory_by_default() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(PurgeConstants.PROPERTY_CLEAN_DIRECTORY, false);
     settings.setProperty(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES, 5);
     Date now = new Date();
@@ -68,7 +69,7 @@ public class PurgeConfigurationTest {
 
   @Test
   public void delete_directory_if_in_settings() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(PurgeConstants.PROPERTY_CLEAN_DIRECTORY, true);
 
     PurgeConfiguration underTest = PurgeConfiguration.newDefaultPurgeConfiguration(settings, new IdUuidPair(42L, "any-uuid"), Collections.emptyList());
index f3971eb7fb7db80d292206b32fa5539135f9046c..fc7e4b169ad017f98d2033983f84b7face8a76cd 100644 (file)
@@ -62,6 +62,7 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.internal.ApiVersion;
 import org.sonar.api.internal.SonarRuntimeImpl;
 import org.sonar.api.measures.Metric;
@@ -95,7 +96,7 @@ public class SensorContextTester implements SensorContext {
   private boolean cancelled;
 
   private SensorContextTester(Path moduleBaseDir) {
-    this.settings = new Settings();
+    this.settings = new MapSettings();
     this.fs = new DefaultFileSystem(moduleBaseDir);
     this.activeRules = new ActiveRulesBuilder().build();
     this.sensorStorage = new InMemorySensorStorage();
index f07affe47677a3c272d73c2fc6d1a1792ffd4c42..03d40bc4822cd6dfb7ee0b4c64541883464a9b9e 100644 (file)
@@ -44,8 +44,8 @@ public final class Encryption {
   public Encryption(@Nullable String pathToSecretKey) {
     aesCipher = new AesCipher(pathToSecretKey);
     ciphers = ImmutableMap.of(
-        BASE64_ALGORITHM, new Base64Cipher(),
-        AES_ALGORITHM, aesCipher);
+      BASE64_ALGORITHM, new Base64Cipher(),
+      AES_ALGORITHM, aesCipher);
   }
 
   public void setPathToSecretKey(@Nullable String pathToSecretKey) {
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/config/MapSettings.java b/sonar-plugin-api/src/main/java/org/sonar/api/config/MapSettings.java
new file mode 100644 (file)
index 0000000..d872688
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.config;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * In-memory map-based implementation of {@link Settings}. It must be used
+ * <b>only for unit tests</b>. This is not the implementation
+ * deployed at runtime, so non-test code must never cast
+ * {@link Settings} to {@link MapSettings}.
+ *
+ * @since 6.1
+ */
+public class MapSettings extends Settings {
+
+  private final Map<String, String> props = new HashMap<>();
+
+  public MapSettings() {
+    super(new PropertyDefinitions(), new Encryption(null));
+  }
+
+  public MapSettings(PropertyDefinitions definitions) {
+    super(definitions, new Encryption(null));
+  }
+
+  @Override
+  protected Optional<String> get(String key) {
+    return Optional.ofNullable(props.get(key));
+  }
+
+  @Override
+  protected void set(String key, String value) {
+    props.put(key, value);
+  }
+
+  @Override
+  protected void remove(String key) {
+    props.remove(key);
+  }
+
+  @Override
+  public Map<String, String> getProperties() {
+    return ImmutableMap.copyOf(props);
+  }
+
+  public MapSettings clear() {
+    props.clear();
+    return this;
+  }
+}
index f2cdf1aad8d22cb7e1f79c72f2664aa96d14c75c..aa3f3bdc7608ee22b73894df75e60b9949a8465f 100644 (file)
@@ -22,13 +22,13 @@ package org.sonar.api.config;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Properties;
+import java.util.stream.Collectors;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.ArrayUtils;
@@ -38,7 +38,11 @@ import org.sonar.api.ce.ComputeEngineSide;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.utils.DateUtils;
 
+import static java.util.Objects.requireNonNull;
+import static org.apache.commons.lang.StringUtils.trim;
+
 /**
+ *
  * Project settings on batch side, or global settings on server side. This component does not access to database, so
  * property changed via setter methods are not persisted.
  * <br>
@@ -55,7 +59,7 @@ import org.sonar.api.utils.DateUtils;
  *     defaultValue = "A default value",
  *     name = "My property"),
  * })
- * public class MyPlugin extends SonarPlugin {
+ * class MyPlugin extends SonarPlugin {
  * </code>
  * </pre>
  * then you can use:
@@ -67,8 +71,8 @@ import org.sonar.api.utils.DateUtils;
  * <li>If you are using the {@link PropertyDefinition#builder(String)} way like:
  * <pre>
  * <code>
- * public class MyPlugin extends SonarPlugin {
- *     public List getExtensions() {
+ * class MyPlugin extends SonarPlugin {
+ *     List getExtensions() {
  *       return Arrays.asList(
  *         PropertyDefinition.builder("sonar.myProp").name("My property").defaultValue("A default value").build()
  *       );
@@ -83,89 +87,130 @@ import org.sonar.api.utils.DateUtils;
  * </pre>
  * </li>
  * </ul>
- * 
+ *
+ * History - this class is abstract since 6.1.
  * @since 2.12
  */
 @ScannerSide
 @ServerSide
 @ComputeEngineSide
-public class Settings {
+public abstract class Settings {
 
-  protected Map<String, String> properties;
-  protected PropertyDefinitions definitions;
-  private Encryption encryption;
+  private final PropertyDefinitions definitions;
+  private final Encryption encryption;
 
-  public Settings() {
-    this(new PropertyDefinitions());
+  protected Settings(PropertyDefinitions definitions, Encryption encryption) {
+    this.definitions = requireNonNull(definitions);
+    this.encryption = requireNonNull(encryption);
   }
 
-  public Settings(PropertyDefinitions definitions) {
-    this.properties = Maps.newHashMap();
-    this.definitions = definitions;
-    this.encryption = new Encryption(null);
+  protected abstract Optional<String> get(String key);
+
+  protected abstract void set(String key, String value);
+
+  protected abstract void remove(String key);
+
+  /**
+   * Immutable map of the properties that have non-default values.
+   * The default values defined by {@link PropertyDefinitions} are ignored,
+   * so the returned values are not the effective values. Basically only
+   * the non-empty results of {@link #getRawString(String)} are returned.
+   * <p>
+   * Values are not decrypted if they are encrypted with a secret key.
+   * </p>
+   */
+  public abstract Map<String, String> getProperties();
+
+  // FIXME scope to be replaced by "protected" as soon as not used by JRubyFacade
+  public Encryption getEncryption() {
+    return encryption;
   }
 
   /**
-   * Clone settings. Actions are not propagated to cloned settings.
+   * The value that overrides the default value. It
+   * may be encrypted with a secret key. Use {@link #getString(String)} to get
+   * the effective and decrypted value.
    *
-   * @since 3.1
+   * @since 6.1
    */
-  public Settings(Settings other) {
-    this.properties = Maps.newHashMap(other.getProperties());
-    this.definitions = other.getDefinitions();
-    this.encryption = other.getEncryption();
+  public Optional<String> getRawString(String key) {
+    return get(definitions.validKey(requireNonNull(key)));
   }
 
-  public Encryption getEncryption() {
-    return encryption;
+  /**
+   * All the property definitions declared by core and plugins.
+   */
+  public PropertyDefinitions getDefinitions() {
+    return definitions;
   }
 
-  @CheckForNull
-  public String getDefaultValue(String key) {
-    return definitions.getDefaultValue(key);
+  /**
+   * The definition related to the specified property. It may
+   * be empty.
+   *
+   * @since 6.1
+   */
+  public Optional<PropertyDefinition> getDefinition(String key) {
+    return Optional.ofNullable(definitions.get(key));
   }
 
+  /**
+   * @return {@code true} if the property has a non-default value, else {@code false}.
+   */
   public boolean hasKey(String key) {
-    return properties.containsKey(key);
+    return getRawString(key).isPresent();
+  }
+
+  @CheckForNull
+  public String getDefaultValue(String key) {
+    return definitions.getDefaultValue(key);
   }
 
   public boolean hasDefaultValue(String key) {
     return StringUtils.isNotEmpty(getDefaultValue(key));
   }
 
+  /**
+   * The effective value of the specified property. Can return
+   * {@code null} if the property is not set and has no
+   * defined default value.
+   * <p>
+   * If the property is encrypted with a secret key,
+   * then the returned value is decrypted.
+   * </p>
+   *
+   * @throws IllegalStateException if value is encrypted but fails to be decrypted.
+   */
   @CheckForNull
   public String getString(String key) {
-    String value = getClearString(key);
-    if (value != null && encryption.isEncrypted(value)) {
+    String effectiveKey = definitions.validKey(key);
+    Optional<String> value = getRawString(effectiveKey);
+    if (!value.isPresent()) {
+      // default values cannot be encrypted, so return value as-is.
+      return getDefaultValue(effectiveKey);
+    }
+    if (encryption.isEncrypted(value.get())) {
       try {
-        value = encryption.decrypt(value);
+        return encryption.decrypt(value.get());
       } catch (Exception e) {
-        throw new IllegalStateException("Fail to decrypt the property " + key + ". Please check your secret key.", e);
+        throw new IllegalStateException("Fail to decrypt the property " + effectiveKey + ". Please check your secret key.", e);
       }
     }
-    return value;
+    return value.get();
   }
 
   /**
-   * Does not decrypt value.
+   * Effective value as boolean. It is {@code false} if {@link #getString(String)}
+   * does not return {@code "true"}, even if it's not a boolean representation.
+   * @return {@code true} if the effective value is {@code "true"}, else {@code false}.
    */
-  @CheckForNull
-  protected String getClearString(String key) {
-    doOnGetProperties(key);
-    String validKey = definitions.validKey(key);
-    String value = properties.get(validKey);
-    if (value == null) {
-      value = getDefaultValue(validKey);
-    }
-    return value;
-  }
-
   public boolean getBoolean(String key) {
     String value = getString(key);
     return StringUtils.isNotEmpty(value) && Boolean.parseBoolean(value);
   }
 
   /**
+   * Effective value as int.
    * @return the value as int. If the property does not exist and has no default value, then 0 is returned.
    */
   public int getInt(String key) {
@@ -239,8 +284,8 @@ public class Settings {
    * </ul>
    */
   public String[] getStringArray(String key) {
-    PropertyDefinition property = getDefinitions().get(key);
-    if ((null != property) && (property.multiValues())) {
+    Optional<PropertyDefinition> def = getDefinition(key);
+    if ((def.isPresent()) && (def.get().multiValues())) {
       String value = getString(key);
       if (value == null) {
         return ArrayUtils.EMPTY_STRING_ARRAY;
@@ -271,7 +316,7 @@ public class Settings {
   }
 
   /**
-   * Value is splitted and trimmed.
+   * Value is split and trimmed.
    */
   public String[] getStringArrayBySeparator(String key, String separator) {
     String value = getString(key);
@@ -279,36 +324,27 @@ public class Settings {
       String[] strings = StringUtils.splitByWholeSeparator(value, separator);
       String[] result = new String[strings.length];
       for (int index = 0; index < strings.length; index++) {
-        result[index] = StringUtils.trim(strings[index]);
+        result[index] = trim(strings[index]);
       }
       return result;
     }
     return ArrayUtils.EMPTY_STRING_ARRAY;
   }
 
-  public List<String> getKeysStartingWith(String prefix) {
-    List<String> result = new ArrayList<>();
-    for (String key : properties.keySet()) {
-      if (StringUtils.startsWith(key, prefix)) {
-        result.add(key);
-      }
-    }
-    return result;
-  }
-
-  public Settings appendProperty(String key, String value) {
-    String newValue = properties.get(definitions.validKey(key));
-    if (StringUtils.isEmpty(newValue)) {
-      newValue = StringUtils.trim(value);
+  public Settings appendProperty(String key, @Nullable String value) {
+    Optional<String> existingValue = getRawString(definitions.validKey(key));
+    String newValue;
+    if (!existingValue.isPresent()) {
+      newValue = trim(value);
     } else {
-      newValue += "," + StringUtils.trim(value);
+      newValue = existingValue.get() + "," + trim(value);
     }
     return setProperty(key, newValue);
   }
 
   public Settings setProperty(String key, @Nullable String[] values) {
-    PropertyDefinition property = getDefinitions().get(key);
-    if ((null == property) || (!property.multiValues())) {
+    Optional<PropertyDefinition> def = getDefinition(key);
+    if (!def.isPresent() || (!def.get().multiValues())) {
       throw new IllegalStateException("Fail to set multiple values on a single value property " + key);
     }
 
@@ -324,7 +360,7 @@ public class Settings {
       }
 
       String escapedValue = Joiner.on(',').join(escaped);
-      text = StringUtils.trim(escapedValue);
+      text = trim(escapedValue);
     }
     return setProperty(key, text);
   }
@@ -332,11 +368,10 @@ public class Settings {
   public Settings setProperty(String key, @Nullable String value) {
     String validKey = definitions.validKey(key);
     if (value == null) {
-      properties.remove(validKey);
-      doOnRemoveProperty(validKey);
+      removeProperty(validKey);
+
     } else {
-      properties.put(validKey, StringUtils.trim(value));
-      doOnSetProperty(validKey, value);
+      set(validKey, trim(value));
     }
     return this;
   }
@@ -379,11 +414,6 @@ public class Settings {
     return this;
   }
 
-  public Settings setProperties(Map<String, String> props) {
-    clear();
-    return addProperties(props);
-  }
-
   public Settings setProperty(String key, @Nullable Date date, boolean includeTime) {
     if (date == null) {
       return removeProperty(key);
@@ -392,48 +422,14 @@ public class Settings {
   }
 
   public Settings removeProperty(String key) {
-    return setProperty(key, (String) null);
-  }
-
-  public Settings clear() {
-    properties.clear();
-    doOnClearProperties();
+    remove(key);
     return this;
   }
 
-  /**
-   *
-   * @return immutable copy of properties. Encrypted values are kept and not decrypted.
-   */
-  public Map<String, String> getProperties() {
-    return ImmutableMap.copyOf(properties);
-  }
-
-  public PropertyDefinitions getDefinitions() {
-    return definitions;
-  }
-
-  /**
-   * Create empty settings. Definition of available properties is loaded from the given annotated class.
-   * This method is usually used by unit tests.
-   */
-  public static Settings createForComponent(Object component) {
-    return new Settings(new PropertyDefinitions(component));
-  }
-
-  protected void doOnSetProperty(String key, @Nullable String value) {
-    // can be overridden
-  }
-
-  protected void doOnRemoveProperty(String key) {
-    // can be overridden
-  }
-
-  protected void doOnClearProperties() {
-    // can be overridden
+  public List<String> getKeysStartingWith(String prefix) {
+    return getProperties().keySet().stream()
+      .filter(key -> StringUtils.startsWith(key, prefix))
+      .collect(Collectors.toList());
   }
 
-  protected void doOnGetProperties(String key) {
-    // can be overridden
-  }
 }
index 6fbf0bdfdc7bf93d95c2b4d38cca65c133652a6e..5bb9adc01ebb34f32df37e301f81516df9a0c131 100644 (file)
  */
 package org.sonar.api.batch.bootstrap;
 
+import java.io.File;
 import org.junit.Test;
 import org.sonar.api.batch.bootstrap.internal.ProjectBuilderContext;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
-
-import java.io.File;
-
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
-import static org.junit.matchers.JUnitMatchers.hasItem;
 
 public class ProjectBuilderTest {
 
@@ -38,7 +36,7 @@ public class ProjectBuilderTest {
     // this reactor is created and provided by Sonar
     final ProjectReactor projectReactor = new ProjectReactor(ProjectDefinition.create());
 
-    ProjectBuilder builder = new ProjectBuilderSample(new Settings());
+    ProjectBuilder builder = new ProjectBuilderSample(new MapSettings());
     builder.build(new ProjectBuilderContext(projectReactor));
 
     assertThat(projectReactor.getProjects().size(), is(2));
index 96310b7097743f7b4d95fe8bff7d83b97795b2eb..c5772e3b3499b948fa074ec2a2c9824caa681bd4 100644 (file)
@@ -23,6 +23,7 @@ import org.junit.Test;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
@@ -42,7 +43,7 @@ public class DefaultCpdTokensTest {
   @Test
   public void save_no_tokens() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    DefaultCpdTokens tokens = new DefaultCpdTokens(new Settings(), sensorStorage)
+    DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
       .onFile(INPUT_FILE);
 
     tokens.save();
@@ -55,7 +56,7 @@ public class DefaultCpdTokensTest {
   @Test
   public void save_one_token() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    DefaultCpdTokens tokens = new DefaultCpdTokens(new Settings(), sensorStorage)
+    DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
       .onFile(INPUT_FILE)
       .addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo");
 
@@ -69,7 +70,7 @@ public class DefaultCpdTokensTest {
   @Test
   public void handle_exclusions_by_pattern() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("sonar.cpd.exclusions", "src/Foo.java,another");
     DefaultCpdTokens tokens = new DefaultCpdTokens(settings, sensorStorage)
       .onFile(INPUT_FILE)
@@ -85,7 +86,7 @@ public class DefaultCpdTokensTest {
   @Test
   public void save_many_tokens() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    DefaultCpdTokens tokens = new DefaultCpdTokens(new Settings(), sensorStorage)
+    DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
       .onFile(INPUT_FILE)
       .addToken(INPUT_FILE.newRange(1, 2, 1, 5), "foo")
       .addToken(INPUT_FILE.newRange(1, 6, 1, 10), "bar")
@@ -106,7 +107,7 @@ public class DefaultCpdTokensTest {
   @Test
   public void basic_validation() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    DefaultCpdTokens tokens = new DefaultCpdTokens(new Settings(), sensorStorage);
+    DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage);
     try {
       tokens.save();
       fail("Expected exception");
@@ -136,7 +137,7 @@ public class DefaultCpdTokensTest {
   @Test
   public void validate_tokens_order() {
     SensorStorage sensorStorage = mock(SensorStorage.class);
-    DefaultCpdTokens tokens = new DefaultCpdTokens(new Settings(), sensorStorage)
+    DefaultCpdTokens tokens = new DefaultCpdTokens(new MapSettings(), sensorStorage)
       .onFile(INPUT_FILE)
       .addToken(INPUT_FILE.newRange(1, 6, 1, 10), "bar");
 
index 79f96f23e553c51ba5e736b3637a198c285cc637..807d866377345133a0d948d306cf907dc06d8b80 100644 (file)
@@ -42,6 +42,7 @@ import org.sonar.api.batch.sensor.highlighting.TypeOfText;
 import org.sonar.api.batch.sensor.issue.NewIssue;
 import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.utils.SonarException;
@@ -69,7 +70,7 @@ public class SensorContextTesterTest {
 
   @Test
   public void testSettings() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("foo", "bar");
     tester.setSettings(settings);
     assertThat(tester.settings().getString("foo")).isEqualTo("bar");
index 4f326137891f26d9745fd3a383bb8a4042ec8045..2c395c980ca562f008a3862fa2aa31fdc74acab2 100644 (file)
  */
 package org.sonar.api.config;
 
-import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
-import org.sonar.api.config.EmailSettings;
-import org.sonar.api.config.Settings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class EmailSettingsTest {
-  EmailSettings emailSettings;
 
-  @Before
-  public void setUp() {
-    emailSettings = new EmailSettings(new Settings());
-  }
+  private EmailSettings underTest = new EmailSettings(new MapSettings());
 
   @Test
   public void should_return_default_values() {
-    assertThat(emailSettings.getSmtpHost()).isEqualTo("");
-    assertThat(emailSettings.getSmtpPort()).isEqualTo(25);
-    assertThat(emailSettings.getSmtpUsername()).isEmpty();
-    assertThat(emailSettings.getSmtpPassword()).isEmpty();
-    assertThat(emailSettings.getSecureConnection()).isEmpty();
-    assertThat(emailSettings.getFrom()).isEqualTo("noreply@nowhere");
-    assertThat(emailSettings.getPrefix()).isEqualTo("[SONARQUBE]");
-    assertThat(emailSettings.getServerBaseURL()).isEqualTo(CoreProperties.SERVER_BASE_URL_DEFAULT_VALUE);
+    assertThat(underTest.getSmtpHost()).isEqualTo("");
+    assertThat(underTest.getSmtpPort()).isEqualTo(25);
+    assertThat(underTest.getSmtpUsername()).isEmpty();
+    assertThat(underTest.getSmtpPassword()).isEmpty();
+    assertThat(underTest.getSecureConnection()).isEmpty();
+    assertThat(underTest.getFrom()).isEqualTo("noreply@nowhere");
+    assertThat(underTest.getPrefix()).isEqualTo("[SONARQUBE]");
+    assertThat(underTest.getServerBaseURL()).isEqualTo(CoreProperties.SERVER_BASE_URL_DEFAULT_VALUE);
   }
 }
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/MapSettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/MapSettingsTest.java
new file mode 100644 (file)
index 0000000..e4ba990
--- /dev/null
@@ -0,0 +1,427 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.api.config;
+
+import java.util.Date;
+import org.assertj.core.data.Offset;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
+import org.sonar.api.PropertyType;
+import org.sonar.api.utils.DateUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MapSettingsTest {
+
+  private PropertyDefinitions definitions;
+
+  @Properties({
+    @Property(key = "hello", name = "Hello", defaultValue = "world"),
+    @Property(key = "date", name = "Date", defaultValue = "2010-05-18"),
+    @Property(key = "datetime", name = "DateTime", defaultValue = "2010-05-18T15:50:45+0100"),
+    @Property(key = "boolean", name = "Boolean", defaultValue = "true"),
+    @Property(key = "falseboolean", name = "False Boolean", defaultValue = "false"),
+    @Property(key = "integer", name = "Integer", defaultValue = "12345"),
+    @Property(key = "array", name = "Array", defaultValue = "one,two,three"),
+    @Property(key = "multi_values", name = "Array", defaultValue = "1,2,3", multiValues = true),
+    @Property(key = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET, propertySetKey = "jira"),
+    @Property(key = "newKey", name = "New key", deprecatedKey = "oldKey"),
+    @Property(key = "newKeyWithDefaultValue", name = "New key with default value", deprecatedKey = "oldKeyWithDefaultValue", defaultValue = "default_value"),
+    @Property(key = "new_multi_values", name = "New multi values", defaultValue = "1,2,3", multiValues = true, deprecatedKey = "old_multi_values")
+  })
+  private static class Init {
+  }
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  @Before
+  public void init_definitions() {
+    definitions = new PropertyDefinitions();
+    definitions.addComponent(Init.class);
+  }
+
+  @Test
+  public void default_values_should_be_loaded_from_definitions() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getDefaultValue("hello")).isEqualTo("world");
+  }
+
+  @Test
+  public void set_property_int() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", 123);
+    assertThat(settings.getInt("foo")).isEqualTo(123);
+    assertThat(settings.getString("foo")).isEqualTo("123");
+    assertThat(settings.getBoolean("foo")).isFalse();
+  }
+
+  @Test
+  public void default_number_values_are_zero() {
+    Settings settings = new MapSettings();
+    assertThat(settings.getInt("foo")).isEqualTo(0);
+    assertThat(settings.getLong("foo")).isEqualTo(0L);
+  }
+
+  @Test
+  public void getInt_value_must_be_valid() {
+    thrown.expect(NumberFormatException.class);
+
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "not a number");
+    settings.getInt("foo");
+  }
+
+  @Test
+  public void all_values_should_be_trimmed_set_property() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "   FOO ");
+    assertThat(settings.getString("foo")).isEqualTo("FOO");
+  }
+
+  @Test
+  public void test_get_default_value() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getDefaultValue("unknown")).isNull();
+  }
+
+  @Test
+  public void test_get_string() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("hello", "Russia");
+    assertThat(settings.getString("hello")).isEqualTo("Russia");
+  }
+
+  @Test
+  public void setProperty_date() {
+    Settings settings = new MapSettings();
+    Date date = DateUtils.parseDateTime("2010-05-18T15:50:45+0100");
+    settings.setProperty("aDate", date);
+    settings.setProperty("aDateTime", date, true);
+
+    assertThat(settings.getString("aDate")).isEqualTo("2010-05-18");
+    assertThat(settings.getString("aDateTime")).startsWith("2010-05-18T");
+  }
+
+  @Test
+  public void test_get_date() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getDate("unknown")).isNull();
+    assertThat(settings.getDate("date").getDate()).isEqualTo(18);
+    assertThat(settings.getDate("date").getMonth()).isEqualTo(4);
+  }
+
+  @Test
+  public void test_get_date_not_found() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getDate("unknown")).isNull();
+  }
+
+  @Test
+  public void test_get_datetime() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getDateTime("unknown")).isNull();
+    assertThat(settings.getDateTime("datetime").getDate()).isEqualTo(18);
+    assertThat(settings.getDateTime("datetime").getMonth()).isEqualTo(4);
+    assertThat(settings.getDateTime("datetime").getMinutes()).isEqualTo(50);
+  }
+
+  @Test
+  public void test_get_double() {
+    Settings settings = new MapSettings();
+    settings.setProperty("from_double", 3.14159);
+    settings.setProperty("from_string", "3.14159");
+    assertThat(settings.getDouble("from_double")).isEqualTo(3.14159, Offset.offset(0.00001));
+    assertThat(settings.getDouble("from_string")).isEqualTo(3.14159, Offset.offset(0.00001));
+    assertThat(settings.getDouble("unknown")).isNull();
+  }
+
+  @Test
+  public void test_get_float() {
+    Settings settings = new MapSettings();
+    settings.setProperty("from_float", 3.14159f);
+    settings.setProperty("from_string", "3.14159");
+    assertThat(settings.getDouble("from_float")).isEqualTo(3.14159f, Offset.offset(0.00001));
+    assertThat(settings.getDouble("from_string")).isEqualTo(3.14159f, Offset.offset(0.00001));
+    assertThat(settings.getDouble("unknown")).isNull();
+  }
+
+  @Test
+  public void test_get_bad_float() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "bar");
+
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("The property 'foo' is not a float value");
+    settings.getFloat("foo");
+  }
+
+  @Test
+  public void test_get_bad_double() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "bar");
+
+    thrown.expect(IllegalStateException.class);
+    thrown.expectMessage("The property 'foo' is not a double value");
+    settings.getDouble("foo");
+  }
+
+  @Test
+  public void testSetNullFloat() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", (Float) null);
+    assertThat(settings.getFloat("foo")).isNull();
+  }
+
+  @Test
+  public void testSetNullDouble() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", (Double) null);
+    assertThat(settings.getDouble("foo")).isNull();
+  }
+
+  @Test
+  public void getStringArray() {
+    Settings settings = new MapSettings(definitions);
+    String[] array = settings.getStringArray("array");
+    assertThat(array).isEqualTo(new String[] {"one", "two", "three"});
+  }
+
+  @Test
+  public void setStringArray() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("multi_values", new String[] {"A", "B"});
+    String[] array = settings.getStringArray("multi_values");
+    assertThat(array).isEqualTo(new String[] {"A", "B"});
+  }
+
+  @Test
+  public void setStringArrayTrimValues() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("multi_values", new String[] {" A ", " B "});
+    String[] array = settings.getStringArray("multi_values");
+    assertThat(array).isEqualTo(new String[] {"A", "B"});
+  }
+
+  @Test
+  public void setStringArrayEscapeCommas() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("multi_values", new String[] {"A,B", "C,D"});
+    String[] array = settings.getStringArray("multi_values");
+    assertThat(array).isEqualTo(new String[] {"A,B", "C,D"});
+  }
+
+  @Test
+  public void setStringArrayWithEmptyValues() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("multi_values", new String[] {"A,B", "", "C,D"});
+    String[] array = settings.getStringArray("multi_values");
+    assertThat(array).isEqualTo(new String[] {"A,B", "", "C,D"});
+  }
+
+  @Test
+  public void setStringArrayWithNullValues() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("multi_values", new String[] {"A,B", null, "C,D"});
+    String[] array = settings.getStringArray("multi_values");
+    assertThat(array).isEqualTo(new String[] {"A,B", "", "C,D"});
+  }
+
+  @Test(expected = IllegalStateException.class)
+  public void shouldFailToSetArrayValueOnSingleValueProperty() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("array", new String[] {"A", "B", "C"});
+  }
+
+  @Test
+  public void getStringArray_no_value() {
+    Settings settings = new MapSettings();
+    String[] array = settings.getStringArray("array");
+    assertThat(array).isEmpty();
+  }
+
+  @Test
+  public void shouldTrimArray() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "  one,  two, three  ");
+    String[] array = settings.getStringArray("foo");
+    assertThat(array).isEqualTo(new String[] {"one", "two", "three"});
+  }
+
+  @Test
+  public void shouldKeepEmptyValuesWhenSplitting() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "  one,  , two");
+    String[] array = settings.getStringArray("foo");
+    assertThat(array).isEqualTo(new String[] {"one", "", "two"});
+  }
+
+  @Test
+  public void testDefaultValueOfGetString() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getString("hello")).isEqualTo("world");
+  }
+
+  @Test
+  public void set_property_boolean() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", true);
+    settings.setProperty("bar", false);
+    assertThat(settings.getBoolean("foo")).isTrue();
+    assertThat(settings.getBoolean("bar")).isFalse();
+    assertThat(settings.getString("foo")).isEqualTo("true");
+    assertThat(settings.getString("bar")).isEqualTo("false");
+  }
+
+  @Test
+  public void ignore_case_of_boolean_values() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "true");
+    settings.setProperty("bar", "TRUE");
+    // labels in UI
+    settings.setProperty("baz", "True");
+
+    assertThat(settings.getBoolean("foo")).isTrue();
+    assertThat(settings.getBoolean("bar")).isTrue();
+    assertThat(settings.getBoolean("baz")).isTrue();
+  }
+
+  @Test
+  public void get_boolean() {
+    Settings settings = new MapSettings(definitions);
+    assertThat(settings.getBoolean("boolean")).isTrue();
+    assertThat(settings.getBoolean("falseboolean")).isFalse();
+    assertThat(settings.getBoolean("unknown")).isFalse();
+    assertThat(settings.getBoolean("hello")).isFalse();
+  }
+
+  @Test
+  public void shouldCreateByIntrospectingComponent() {
+    Settings settings = new MapSettings();
+    settings.getDefinitions().addComponent(MyComponent.class);
+
+    // property definition has been loaded, ie for default value
+    assertThat(settings.getDefaultValue("foo")).isEqualTo("bar");
+  }
+
+  @Property(key = "foo", name = "Foo", defaultValue = "bar")
+  public static class MyComponent {
+
+  }
+
+  @Test
+  public void getStringLines_no_value() {
+    assertThat(new MapSettings().getStringLines("foo")).hasSize(0);
+  }
+
+  @Test
+  public void getStringLines_single_line() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "the line");
+    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"the line"});
+  }
+
+  @Test
+  public void getStringLines_linux() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "one\ntwo");
+    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
+
+    settings.setProperty("foo", "one\ntwo\n");
+    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
+  }
+
+  @Test
+  public void getStringLines_windows() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "one\r\ntwo");
+    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
+
+    settings.setProperty("foo", "one\r\ntwo\r\n");
+    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
+  }
+
+  @Test
+  public void getStringLines_mix() {
+    Settings settings = new MapSettings();
+    settings.setProperty("foo", "one\r\ntwo\nthree");
+    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two", "three"});
+  }
+
+  @Test
+  public void getKeysStartingWith() {
+    Settings settings = new MapSettings();
+    settings.setProperty("sonar.jdbc.url", "foo");
+    settings.setProperty("sonar.jdbc.username", "bar");
+    settings.setProperty("sonar.security", "admin");
+
+    assertThat(settings.getKeysStartingWith("sonar")).containsOnly("sonar.jdbc.url", "sonar.jdbc.username", "sonar.security");
+    assertThat(settings.getKeysStartingWith("sonar.jdbc")).containsOnly("sonar.jdbc.url", "sonar.jdbc.username");
+    assertThat(settings.getKeysStartingWith("other")).hasSize(0);
+  }
+
+  @Test
+  public void should_fallback_deprecated_key_to_default_value_of_new_key() {
+    Settings settings = new MapSettings(definitions);
+
+    assertThat(settings.getString("newKeyWithDefaultValue")).isEqualTo("default_value");
+    assertThat(settings.getString("oldKeyWithDefaultValue")).isEqualTo("default_value");
+  }
+
+  @Test
+  public void should_fallback_deprecated_key_to_new_key() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("newKey", "value of newKey");
+
+    assertThat(settings.getString("newKey")).isEqualTo("value of newKey");
+    assertThat(settings.getString("oldKey")).isEqualTo("value of newKey");
+  }
+
+  @Test
+  public void should_load_value_of_deprecated_key() {
+    // it's used for example when deprecated settings are set through command-line
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("oldKey", "value of oldKey");
+
+    assertThat(settings.getString("newKey")).isEqualTo("value of oldKey");
+    assertThat(settings.getString("oldKey")).isEqualTo("value of oldKey");
+  }
+
+  @Test
+  public void should_load_values_of_deprecated_key() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("oldKey", "a,b");
+
+    assertThat(settings.getStringArray("newKey")).containsOnly("a", "b");
+    assertThat(settings.getStringArray("oldKey")).containsOnly("a", "b");
+  }
+
+  @Test
+  public void should_support_deprecated_props_with_multi_values() {
+    Settings settings = new MapSettings(definitions);
+    settings.setProperty("new_multi_values", new String[] {" A ", " B "});
+    assertThat(settings.getStringArray("new_multi_values")).isEqualTo(new String[] {"A", "B"});
+    assertThat(settings.getStringArray("old_multi_values")).isEqualTo(new String[] {"A", "B"});
+  }
+}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/config/SettingsTest.java
deleted file mode 100644 (file)
index 58822ca..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.api.config;
-
-import com.google.common.collect.ImmutableMap;
-import org.assertj.core.data.Offset;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.Properties;
-import org.sonar.api.Property;
-import org.sonar.api.PropertyType;
-import org.sonar.api.utils.DateUtils;
-
-import java.util.Date;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class SettingsTest {
-
-  private PropertyDefinitions definitions;
-
-  @Properties({
-    @Property(key = "hello", name = "Hello", defaultValue = "world"),
-    @Property(key = "date", name = "Date", defaultValue = "2010-05-18"),
-    @Property(key = "datetime", name = "DateTime", defaultValue = "2010-05-18T15:50:45+0100"),
-    @Property(key = "boolean", name = "Boolean", defaultValue = "true"),
-    @Property(key = "falseboolean", name = "False Boolean", defaultValue = "false"),
-    @Property(key = "integer", name = "Integer", defaultValue = "12345"),
-    @Property(key = "array", name = "Array", defaultValue = "one,two,three"),
-    @Property(key = "multi_values", name = "Array", defaultValue = "1,2,3", multiValues = true),
-    @Property(key = "sonar.jira", name = "Jira Server", type = PropertyType.PROPERTY_SET, propertySetKey = "jira"),
-    @Property(key = "newKey", name = "New key", deprecatedKey = "oldKey"),
-    @Property(key = "newKeyWithDefaultValue", name = "New key with default value", deprecatedKey = "oldKeyWithDefaultValue", defaultValue = "default_value"),
-    @Property(key = "new_multi_values", name = "New multi values", defaultValue = "1,2,3", multiValues = true, deprecatedKey = "old_multi_values")
-  })
-  static class Init {
-  }
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @Before
-  public void init_definitions() {
-    definitions = new PropertyDefinitions();
-    definitions.addComponent(Init.class);
-  }
-
-  @Test
-  public void default_values_should_be_loaded_from_definitions() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getDefaultValue("hello")).isEqualTo("world");
-  }
-
-  @Test
-  public void set_property_int() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", 123);
-    assertThat(settings.getInt("foo")).isEqualTo(123);
-    assertThat(settings.getString("foo")).isEqualTo("123");
-    assertThat(settings.getBoolean("foo")).isFalse();
-  }
-
-  @Test
-  public void default_number_values_are_zero() {
-    Settings settings = new Settings();
-    assertThat(settings.getInt("foo")).isEqualTo(0);
-    assertThat(settings.getLong("foo")).isEqualTo(0L);
-  }
-
-  @Test
-  public void getInt_value_must_be_valid() {
-    thrown.expect(NumberFormatException.class);
-
-    Settings settings = new Settings();
-    settings.setProperty("foo", "not a number");
-    settings.getInt("foo");
-  }
-
-  @Test
-  public void all_values_should_be_trimmed_set_property() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "   FOO ");
-    assertThat(settings.getString("foo")).isEqualTo("FOO");
-  }
-
-  @Test
-  public void all_values_should_be_trimmed_set_properties() {
-    Settings settings = new Settings();
-    settings.setProperties(ImmutableMap.of("foo", "  FOO "));
-    assertThat(settings.getString("foo")).isEqualTo("FOO");
-  }
-
-  @Test
-  public void test_get_default_value() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getDefaultValue("unknown")).isNull();
-  }
-
-  @Test
-  public void test_get_string() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("hello", "Russia");
-    assertThat(settings.getString("hello")).isEqualTo("Russia");
-  }
-
-  @Test
-  public void setProperty_date() {
-    Settings settings = new Settings();
-    Date date = DateUtils.parseDateTime("2010-05-18T15:50:45+0100");
-    settings.setProperty("aDate", date);
-    settings.setProperty("aDateTime", date, true);
-
-    assertThat(settings.getString("aDate")).isEqualTo("2010-05-18");
-    assertThat(settings.getString("aDateTime")).startsWith("2010-05-18T");
-  }
-
-  @Test
-  public void test_get_date() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getDate("unknown")).isNull();
-    assertThat(settings.getDate("date").getDate()).isEqualTo(18);
-    assertThat(settings.getDate("date").getMonth()).isEqualTo(4);
-  }
-
-  @Test
-  public void test_get_date_not_found() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getDate("unknown")).isNull();
-  }
-
-  @Test
-  public void test_get_datetime() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getDateTime("unknown")).isNull();
-    assertThat(settings.getDateTime("datetime").getDate()).isEqualTo(18);
-    assertThat(settings.getDateTime("datetime").getMonth()).isEqualTo(4);
-    assertThat(settings.getDateTime("datetime").getMinutes()).isEqualTo(50);
-  }
-
-  @Test
-  public void test_get_double() {
-    Settings settings = new Settings();
-    settings.setProperty("from_double", 3.14159);
-    settings.setProperty("from_string", "3.14159");
-    assertThat(settings.getDouble("from_double")).isEqualTo(3.14159, Offset.offset(0.00001));
-    assertThat(settings.getDouble("from_string")).isEqualTo(3.14159, Offset.offset(0.00001));
-    assertThat(settings.getDouble("unknown")).isNull();
-  }
-
-  @Test
-  public void test_get_float() {
-    Settings settings = new Settings();
-    settings.setProperty("from_float", 3.14159f);
-    settings.setProperty("from_string", "3.14159");
-    assertThat(settings.getDouble("from_float")).isEqualTo(3.14159f, Offset.offset(0.00001));
-    assertThat(settings.getDouble("from_string")).isEqualTo(3.14159f, Offset.offset(0.00001));
-    assertThat(settings.getDouble("unknown")).isNull();
-  }
-
-  @Test
-  public void test_get_bad_float() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "bar");
-
-    thrown.expect(IllegalStateException.class);
-    thrown.expectMessage("The property 'foo' is not a float value");
-    settings.getFloat("foo");
-  }
-
-  @Test
-  public void test_get_bad_double() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "bar");
-
-    thrown.expect(IllegalStateException.class);
-    thrown.expectMessage("The property 'foo' is not a double value");
-    settings.getDouble("foo");
-  }
-
-  @Test
-  public void testSetNullFloat() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", (Float) null);
-    assertThat(settings.getFloat("foo")).isNull();
-  }
-
-  @Test
-  public void testSetNullDouble() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", (Double) null);
-    assertThat(settings.getDouble("foo")).isNull();
-  }
-
-  @Test
-  public void getStringArray() {
-    Settings settings = new Settings(definitions);
-    String[] array = settings.getStringArray("array");
-    assertThat(array).isEqualTo(new String[] {"one", "two", "three"});
-  }
-
-  @Test
-  public void setStringArray() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("multi_values", new String[] {"A", "B"});
-    String[] array = settings.getStringArray("multi_values");
-    assertThat(array).isEqualTo(new String[] {"A", "B"});
-  }
-
-  @Test
-  public void setStringArrayTrimValues() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("multi_values", new String[] {" A ", " B "});
-    String[] array = settings.getStringArray("multi_values");
-    assertThat(array).isEqualTo(new String[] {"A", "B"});
-  }
-
-  @Test
-  public void setStringArrayEscapeCommas() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("multi_values", new String[] {"A,B", "C,D"});
-    String[] array = settings.getStringArray("multi_values");
-    assertThat(array).isEqualTo(new String[] {"A,B", "C,D"});
-  }
-
-  @Test
-  public void setStringArrayWithEmptyValues() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("multi_values", new String[] {"A,B", "", "C,D"});
-    String[] array = settings.getStringArray("multi_values");
-    assertThat(array).isEqualTo(new String[] {"A,B", "", "C,D"});
-  }
-
-  @Test
-  public void setStringArrayWithNullValues() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("multi_values", new String[] {"A,B", null, "C,D"});
-    String[] array = settings.getStringArray("multi_values");
-    assertThat(array).isEqualTo(new String[] {"A,B", "", "C,D"});
-  }
-
-  @Test(expected = IllegalStateException.class)
-  public void shouldFailToSetArrayValueOnSingleValueProperty() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("array", new String[] {"A", "B", "C"});
-  }
-
-  @Test
-  public void getStringArray_no_value() {
-    Settings settings = new Settings();
-    String[] array = settings.getStringArray("array");
-    assertThat(array).isEmpty();
-  }
-
-  @Test
-  public void shouldTrimArray() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "  one,  two, three  ");
-    String[] array = settings.getStringArray("foo");
-    assertThat(array).isEqualTo(new String[] {"one", "two", "three"});
-  }
-
-  @Test
-  public void shouldKeepEmptyValuesWhenSplitting() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "  one,  , two");
-    String[] array = settings.getStringArray("foo");
-    assertThat(array).isEqualTo(new String[] {"one", "", "two"});
-  }
-
-  @Test
-  public void testDefaultValueOfGetString() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getString("hello")).isEqualTo("world");
-  }
-
-  @Test
-  public void set_property_boolean() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", true);
-    settings.setProperty("bar", false);
-    assertThat(settings.getBoolean("foo")).isTrue();
-    assertThat(settings.getBoolean("bar")).isFalse();
-    assertThat(settings.getString("foo")).isEqualTo("true");
-    assertThat(settings.getString("bar")).isEqualTo("false");
-  }
-
-  @Test
-  public void ignore_case_of_boolean_values() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "true");
-    settings.setProperty("bar", "TRUE");
-    // labels in UI
-    settings.setProperty("baz", "True");
-
-    assertThat(settings.getBoolean("foo")).isTrue();
-    assertThat(settings.getBoolean("bar")).isTrue();
-    assertThat(settings.getBoolean("baz")).isTrue();
-  }
-
-  @Test
-  public void get_boolean() {
-    Settings settings = new Settings(definitions);
-    assertThat(settings.getBoolean("boolean")).isTrue();
-    assertThat(settings.getBoolean("falseboolean")).isFalse();
-    assertThat(settings.getBoolean("unknown")).isFalse();
-    assertThat(settings.getBoolean("hello")).isFalse();
-  }
-
-  @Test
-  public void shouldCreateByIntrospectingComponent() {
-    Settings settings = Settings.createForComponent(MyComponent.class);
-
-    // property definition has been loaded, ie for default value
-    assertThat(settings.getDefaultValue("foo")).isEqualTo("bar");
-  }
-
-  @Property(key = "foo", name = "Foo", defaultValue = "bar")
-  public static class MyComponent {
-
-  }
-
-  @Test
-  public void cloneSettings() {
-    Settings target = new Settings(definitions).setProperty("foo", "bar");
-    Settings settings = new Settings(target);
-
-    assertThat(settings.getString("foo")).isEqualTo("bar");
-    assertThat(settings.getDefinitions()).isSameAs(definitions);
-
-    // do not propagate changes
-    settings.setProperty("foo", "changed");
-    settings.setProperty("new", "value");
-
-    assertThat(settings.getString("foo")).isEqualTo("changed");
-    assertThat(settings.getString("new")).isEqualTo("value");
-    assertThat(target.getString("foo")).isEqualTo("bar");
-    assertThat(target.getString("new")).isNull();
-  }
-
-  @Test
-  public void getStringLines_no_value() {
-    assertThat(new Settings().getStringLines("foo")).hasSize(0);
-  }
-
-  @Test
-  public void getStringLines_single_line() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "the line");
-    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"the line"});
-  }
-
-  @Test
-  public void getStringLines_linux() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "one\ntwo");
-    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
-
-    settings.setProperty("foo", "one\ntwo\n");
-    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
-  }
-
-  @Test
-  public void getStringLines_windows() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "one\r\ntwo");
-    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
-
-    settings.setProperty("foo", "one\r\ntwo\r\n");
-    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two"});
-  }
-
-  @Test
-  public void getStringLines_mix() {
-    Settings settings = new Settings();
-    settings.setProperty("foo", "one\r\ntwo\nthree");
-    assertThat(settings.getStringLines("foo")).isEqualTo(new String[] {"one", "two", "three"});
-  }
-
-  @Test
-  public void getKeysStartingWith() {
-    Settings settings = new Settings();
-    settings.setProperty("sonar.jdbc.url", "foo");
-    settings.setProperty("sonar.jdbc.username", "bar");
-    settings.setProperty("sonar.security", "admin");
-
-    assertThat(settings.getKeysStartingWith("sonar")).containsOnly("sonar.jdbc.url", "sonar.jdbc.username", "sonar.security");
-    assertThat(settings.getKeysStartingWith("sonar.jdbc")).containsOnly("sonar.jdbc.url", "sonar.jdbc.username");
-    assertThat(settings.getKeysStartingWith("other")).hasSize(0);
-  }
-
-  @Test
-  public void should_fallback_deprecated_key_to_default_value_of_new_key() {
-    Settings settings = new Settings(definitions);
-
-    assertThat(settings.getString("newKeyWithDefaultValue")).isEqualTo("default_value");
-    assertThat(settings.getString("oldKeyWithDefaultValue")).isEqualTo("default_value");
-  }
-
-  @Test
-  public void should_fallback_deprecated_key_to_new_key() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("newKey", "value of newKey");
-
-    assertThat(settings.getString("newKey")).isEqualTo("value of newKey");
-    assertThat(settings.getString("oldKey")).isEqualTo("value of newKey");
-  }
-
-  @Test
-  public void should_load_value_of_deprecated_key() {
-    // it's used for example when deprecated settings are set through command-line
-    Settings settings = new Settings(definitions);
-    settings.setProperty("oldKey", "value of oldKey");
-
-    assertThat(settings.getString("newKey")).isEqualTo("value of oldKey");
-    assertThat(settings.getString("oldKey")).isEqualTo("value of oldKey");
-  }
-
-  @Test
-  public void should_load_values_of_deprecated_key() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("oldKey", "a,b");
-
-    assertThat(settings.getStringArray("newKey")).containsOnly("a", "b");
-    assertThat(settings.getStringArray("oldKey")).containsOnly("a", "b");
-  }
-
-  @Test
-  public void should_support_deprecated_props_with_multi_values() {
-    Settings settings = new Settings(definitions);
-    settings.setProperty("new_multi_values", new String[] {" A ", " B "});
-    assertThat(settings.getStringArray("new_multi_values")).isEqualTo(new String[] {"A", "B"});
-    assertThat(settings.getStringArray("old_multi_values")).isEqualTo(new String[] {"A", "B"});
-  }
-}
index dd01bd616b8392945b6ec6e19757aa57b5052fab..373631daff80246c01754ee18d9b422517b6b3dc 100644 (file)
@@ -22,13 +22,14 @@ package org.sonar.api.scan.filesystem;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class FileExclusionsTest {
   @Test
   public void ignore_inclusion_of_world() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*");
     settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/*");
     assertThat(new FileExclusions(settings).sourceInclusions()).isEmpty();
@@ -37,7 +38,7 @@ public class FileExclusionsTest {
 
   @Test
   public void load_inclusions() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Foo.java");
     settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "**/*FooTest.java");
     FileExclusions moduleExclusions = new FileExclusions(settings);
@@ -48,7 +49,7 @@ public class FileExclusionsTest {
 
   @Test
   public void load_exclusions() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Foo.java");
     settings.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, "**/*FooTest.java");
     FileExclusions moduleExclusions = new FileExclusions(settings);
index cbda72dc5f7291887ad31d7492d27eda11376309..409da22f7519e63127e9f9c7caf9b91cdad78602 100644 (file)
@@ -26,6 +26,7 @@ import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.i18n.I18n;
 
 import java.util.Locale;
@@ -54,7 +55,7 @@ public class DurationsTest {
 
   @Before
   public void setUp() {
-    settings = new Settings();
+    settings = new MapSettings();
     settings.setProperty(CoreProperties.HOURS_IN_DAY, HOURS_IN_DAY);
     durations = new Durations(settings, i18n);
   }
index b327d79017af568a04d5e93dc96cec3b30357759..5305f666d39eea3383969f11d1c05bee2619fa1a 100644 (file)
 package org.sonar.scanner.bootstrap;
 
 import com.google.common.collect.ImmutableMap;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.config.Encryption;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.MessageException;
@@ -46,11 +49,12 @@ public class GlobalSettings extends Settings {
   private final GlobalProperties bootstrapProps;
   private final GlobalRepositories globalReferentials;
   private final GlobalMode mode;
+  private final Map<String, String> properties = new HashMap<>();
 
   public GlobalSettings(GlobalProperties bootstrapProps, PropertyDefinitions propertyDefinitions,
     GlobalRepositories globalReferentials, GlobalMode mode) {
 
-    super(propertyDefinitions);
+    super(propertyDefinitions, new Encryption(null));
     this.mode = mode;
     getEncryption().setPathToSecretKey(bootstrapProps.property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
     this.bootstrapProps = bootstrapProps;
@@ -69,10 +73,26 @@ public class GlobalSettings extends Settings {
   }
 
   @Override
-  protected void doOnGetProperties(String key) {
+  protected Optional<String> get(String key) {
     if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) {
       throw MessageException.of("Access to the secured property '" + key
         + "' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode.");
     }
+    return Optional.ofNullable(properties.get(key));
+  }
+
+  @Override
+  public Map<String, String> getProperties() {
+    return properties;
+  }
+
+  @Override
+  protected void set(String key, String value) {
+    properties.put(key, value);
+  }
+
+  @Override
+  protected void remove(String key) {
+    properties.remove(key);
   }
 }
index 59bbd4472bcbd604c8cba2b185a6dbdf4cd01ae8..c5f4dbaa3d7d0abf37d6dc2c8805396011d75a21 100644 (file)
 package org.sonar.scanner.scan;
 
 import com.google.common.collect.Lists;
+import java.util.HashMap;
 import java.util.List;
-import org.sonar.api.CoreProperties;
+import java.util.Map;
+import java.util.Optional;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.MessageException;
@@ -37,13 +39,13 @@ public class ModuleSettings extends Settings {
 
   private final ProjectRepositories projectRepos;
   private final DefaultAnalysisMode analysisMode;
+  private final Map<String, String> properties = new HashMap<>();
 
   public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition moduleDefinition, ProjectRepositories projectSettingsRepo,
     DefaultAnalysisMode analysisMode, AnalysisContextReportPublisher contextReportPublisher) {
-    super(batchSettings.getDefinitions());
+    super(batchSettings.getDefinitions(), batchSettings.getEncryption());
     this.projectRepos = projectSettingsRepo;
     this.analysisMode = analysisMode;
-    getEncryption().setPathToSecretKey(batchSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
 
     init(moduleDefinition, batchSettings);
     contextReportPublisher.dumpModuleSettings(moduleDefinition);
@@ -87,10 +89,26 @@ public class ModuleSettings extends Settings {
   }
 
   @Override
-  protected void doOnGetProperties(String key) {
+  protected Optional<String> get(String key) {
     if (analysisMode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) {
       throw MessageException.of("Access to the secured property '" + key
         + "' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode.");
     }
+    return Optional.ofNullable(properties.get(key));
+  }
+
+  @Override
+  protected void set(String key, String value) {
+    properties.put(key, value);
+  }
+
+  @Override
+  protected void remove(String key) {
+    properties.remove(key);
+  }
+
+  @Override
+  public Map<String, String> getProperties() {
+    return properties;
   }
 }
index c4784114b8b5d57293eb57539d208fa03fe4cb76..9f96c6e9f1e69c671a7af0be9eb41a59b7971de4 100644 (file)
  */
 package org.sonar.scanner.scan;
 
-import org.sonar.api.CoreProperties;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
 import org.sonar.api.batch.bootstrap.ProjectReactor;
-import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.analysis.DefaultAnalysisMode;
@@ -33,12 +34,11 @@ public class ProjectSettings extends Settings {
   private final GlobalSettings globalSettings;
   private final ProjectRepositories projectRepositories;
   private final DefaultAnalysisMode mode;
+  private final Map<String, String> properties = new HashMap<>();
 
-  public ProjectSettings(ProjectReactor reactor, GlobalSettings globalSettings, PropertyDefinitions propertyDefinitions,
-    ProjectRepositories projectRepositories, DefaultAnalysisMode mode) {
-    super(propertyDefinitions);
+  public ProjectSettings(ProjectReactor reactor, GlobalSettings globalSettings, ProjectRepositories projectRepositories, DefaultAnalysisMode mode) {
+    super(globalSettings.getDefinitions(), globalSettings.getEncryption());
     this.mode = mode;
-    getEncryption().setPathToSecretKey(globalSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH));
     this.globalSettings = globalSettings;
     this.projectRepositories = projectRepositories;
     init(reactor);
@@ -53,10 +53,26 @@ public class ProjectSettings extends Settings {
   }
 
   @Override
-  protected void doOnGetProperties(String key) {
+  protected Optional<String> get(String key) {
     if (mode.isIssues() && key.endsWith(".secured") && !key.contains(".license")) {
       throw MessageException.of("Access to the secured property '" + key
         + "' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode.");
     }
+    return Optional.ofNullable(properties.get(key));
+  }
+
+  @Override
+  protected void set(String key, String value) {
+    properties.put(key, value);
+  }
+
+  @Override
+  protected void remove(String key) {
+    properties.remove(key);
+  }
+
+  @Override
+  public Map<String, String> getProperties() {
+    return properties;
   }
 }
index 7e291ee34d34bdd475d7e28abd2c638922043f05..95b1673bf82222a223c29b1ec79b8586fdf71886 100644 (file)
@@ -25,9 +25,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.System2;
-import org.sonar.scanner.ProjectConfigurator;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -48,13 +48,13 @@ public class ProjectConfiguratorTest {
     when(system2.now()).thenReturn(now);
 
     Project project = new Project("key");
-    new ProjectConfigurator(new Settings(), system2).configure(project);
+    new ProjectConfigurator(new MapSettings(), system2).configure(project);
     assertThat(now - project.getAnalysisDate().getTime()).isLessThan(1000);
   }
 
   @Test
   public void analysis_date_could_be_explicitly_set() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-01-30");
     Project project = new Project("key");
     new ProjectConfigurator(settings, system2).configure(project);
@@ -64,7 +64,7 @@ public class ProjectConfiguratorTest {
 
   @Test
   public void analysis_timestamp_could_be_explicitly_set() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-01-30T08:45:10+0000");
     Project project = new Project("key");
     new ProjectConfigurator(settings, system2).configure(project);
@@ -76,7 +76,7 @@ public class ProjectConfiguratorTest {
 
   @Test(expected = RuntimeException.class)
   public void fail_if_analyis_date_is_not_valid() {
-    Settings configuration = new Settings();
+    Settings configuration = new MapSettings();
     configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005/30/01");
     Project project = new Project("key");
     new ProjectConfigurator(configuration, system2).configure(project);
index 99f9d9eb98147d6480bffb8bba9b71d5cab385cf..01f32880499097431422ddf58b8176b9f07bdb07 100644 (file)
@@ -22,8 +22,7 @@ package org.sonar.scanner.bootstrap;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
-import org.sonar.scanner.bootstrap.BatchPluginPredicate;
-import org.sonar.scanner.bootstrap.GlobalMode;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -31,7 +30,7 @@ import static org.mockito.Mockito.when;
 
 public class BatchPluginPredicateTest {
 
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   GlobalMode mode = mock(GlobalMode.class);
 
   @Test
index 251b8c84b281e2054b4bd2f3957c4870e65c3f91..70602d7634f95e5a94aad4e0af7d9bca89bf542d 100644 (file)
@@ -21,13 +21,12 @@ package org.sonar.scanner.bootstrap;
 
 import java.io.File;
 import java.io.IOException;
-
 import org.junit.Rule;
-import org.junit.rules.TemporaryFolder;
 import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.home.cache.FileCache;
-import org.sonar.scanner.bootstrap.FileCacheProvider;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -38,7 +37,7 @@ public class FileCacheProviderTest {
   @Test
   public void provide() {
     FileCacheProvider provider = new FileCacheProvider();
-    FileCache cache = provider.provide(new Settings());
+    FileCache cache = provider.provide(new MapSettings());
 
     assertThat(cache).isNotNull();
     assertThat(cache.getDir()).isNotNull().exists();
@@ -47,7 +46,7 @@ public class FileCacheProviderTest {
   @Test
   public void keep_singleton_instance() {
     FileCacheProvider provider = new FileCacheProvider();
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     FileCache cache1 = provider.provide(settings);
     FileCache cache2 = provider.provide(settings);
 
@@ -57,7 +56,7 @@ public class FileCacheProviderTest {
   @Test
   public void honor_sonarUserHome() throws IOException {
     FileCacheProvider provider = new FileCacheProvider();
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     File f = temp.newFolder();
     settings.appendProperty("sonar.userHome", f.getAbsolutePath());
     FileCache cache = provider.provide(settings);
index 4ae6eaf0e8266394401e6f478e2265011d74c6c1..24d1023ade20232de6ea78e3786415c098c584cd 100644 (file)
@@ -32,21 +32,21 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Project;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.core.util.CloseableIterator;
 import org.sonar.duplications.index.CloneGroup;
 import org.sonar.duplications.index.ClonePart;
-import org.sonar.scanner.protocol.output.ScannerReport.Duplicate;
-import org.sonar.scanner.protocol.output.ScannerReport.Duplication;
-import org.sonar.scanner.report.ReportPublisher;
-import org.sonar.scanner.cpd.CpdExecutor;
 import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
 import org.sonar.scanner.index.BatchComponent;
 import org.sonar.scanner.index.BatchComponentCache;
+import org.sonar.scanner.protocol.output.ScannerReport.Duplicate;
+import org.sonar.scanner.protocol.output.ScannerReport.Duplication;
 import org.sonar.scanner.protocol.output.ScannerReportReader;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.report.ReportPublisher;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -76,7 +76,7 @@ public class CpdExecutorTest {
   public void setUp() throws IOException {
     File outputDir = temp.newFolder();
 
-    settings = new Settings();
+    settings = new MapSettings();
     index = mock(SonarCpdBlockIndex.class);
     publisher = mock(ReportPublisher.class);
     when(publisher.getWriter()).thenReturn(new ScannerReportWriter(outputDir));
index 17338bab8affebbe1232472bceaa5defe42bad0b..f748f296d8a950531c5bccb4fd2b442a4336dace 100644 (file)
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.sonar.api.config.Settings;
-import org.sonar.scanner.cpd.deprecated.DefaultCpdBlockIndexer;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.anyString;
@@ -39,7 +39,7 @@ public class DefaultCpdBlockIndexerTest {
 
   @Before
   public void init() {
-    settings = new Settings();
+    settings = new MapSettings();
     engine = new DefaultCpdBlockIndexer(null, null, settings, null);
   }
 
index d59fb62a858cdfe41fb39a92f25012b161588eea..f43120e5c841753f38c517f26d70ccf7e9222d3f 100644 (file)
@@ -19,6 +19,9 @@
  */
 package org.sonar.scanner.cpd.deprecated;
 
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
 import org.apache.commons.io.FileUtils;
 import org.junit.Before;
 import org.junit.Rule;
@@ -33,13 +36,10 @@ import org.sonar.api.batch.fs.FileSystem;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.duplications.block.Block;
-import org.sonar.scanner.cpd.deprecated.JavaCpdBlockIndexer;
 import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
 import org.sonar.scanner.index.BatchComponentCache;
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.eq;
@@ -76,13 +76,13 @@ public class JavaCpdBlockIndexerTest {
     File ioFile = file.file();
     FileUtils.copyURLToFile(this.getClass().getResource("ManyStatements.java"), ioFile);
 
-    settings = new Settings();
+    settings = new MapSettings();
     engine = new JavaCpdBlockIndexer(fs, settings, index);
   }
 
   @Test
   public void languageSupported() {
-    JavaCpdBlockIndexer engine = new JavaCpdBlockIndexer(mock(FileSystem.class), new Settings(), index);
+    JavaCpdBlockIndexer engine = new JavaCpdBlockIndexer(mock(FileSystem.class), new MapSettings(), index);
     assertThat(engine.isLanguageSupported(JAVA)).isTrue();
     assertThat(engine.isLanguageSupported("php")).isFalse();
   }
index c9fbc50229e583057f1741a481780e74c618bb05..17e18d36f2145fbf6b2863f3396e29fdb97b1fe3 100644 (file)
@@ -24,9 +24,9 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.SonarException;
 import org.sonar.core.config.IssueExclusionProperties;
-import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -38,7 +38,7 @@ public class IssueExclusionPatternInitializerTest {
 
   @Before
   public void init() {
-    settings = new Settings(new PropertyDefinitions(IssueExclusionProperties.all()));
+    settings = new MapSettings(new PropertyDefinitions(IssueExclusionProperties.all()));
     patternsInitializer = new IssueExclusionPatternInitializer(settings);
   }
 
index e34f19ea649ec377bb9f0eefd2d715c706106570..0e323768f64c9d1485e05cad508d36fe1c9ca049 100644 (file)
@@ -23,8 +23,8 @@ import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.core.config.IssueExclusionProperties;
-import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -36,7 +36,7 @@ public class IssueInclusionPatternInitializerTest {
 
   @Before
   public void init() {
-    settings = new Settings(new PropertyDefinitions(IssueExclusionProperties.all()));
+    settings = new MapSettings(new PropertyDefinitions(IssueExclusionProperties.all()));
     patternsInitializer = new IssueInclusionPatternInitializer(settings);
   }
 
index 70fe539966204e26963a102a41d1634a534c92ca..e743714e568b14b470ecead64b1a76dfefdc5bde 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.scanner.platform;
 import org.junit.Test;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.scanner.bootstrap.BatchWsClient;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -32,7 +33,7 @@ public class DefaultServerTest {
 
   @Test
   public void shouldLoadServerProperties() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.SERVER_ID, "123");
     settings.setProperty(CoreProperties.SERVER_VERSION, "2.2");
     settings.setProperty(CoreProperties.SERVER_STARTTIME, "2010-05-18T17:59:00+0000");
@@ -57,7 +58,7 @@ public class DefaultServerTest {
 
   @Test
   public void publicRootUrl() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     BatchWsClient client = mock(BatchWsClient.class);
     when(client.baseUrl()).thenReturn("http://foo.com/");
     DefaultServer metadata = new DefaultServer(settings, client);
@@ -71,7 +72,7 @@ public class DefaultServerTest {
 
   @Test(expected = RuntimeException.class)
   public void invalid_startup_date_throws_exception() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.SERVER_STARTTIME, "invalid");
     BatchWsClient client = mock(BatchWsClient.class);
     DefaultServer metadata = new DefaultServer(settings, client);
index caa182c49c271969e2884b2a7e6c79ed5b284d0f..8a977c8644f7ae4a53893bdb694a0ccd8571dce3 100644 (file)
@@ -27,11 +27,11 @@ import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.postjob.issue.PostJobIssue;
 import org.sonar.api.batch.rule.Severity;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.File;
 import org.sonar.scanner.index.BatchComponentCache;
 import org.sonar.scanner.issue.IssueCache;
 import org.sonar.scanner.issue.tracking.TrackedIssue;
-import org.sonar.scanner.postjob.DefaultPostJobContext;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -49,7 +49,7 @@ public class DefaultPostJobContextTest {
   public void prepare() {
     issueCache = mock(IssueCache.class);
     resourceCache = new BatchComponentCache();
-    settings = new Settings();
+    settings = new MapSettings();
     analysisMode = mock(AnalysisMode.class);
     context = new DefaultPostJobContext(settings, issueCache, resourceCache, analysisMode);
   }
index 3875f6974f01d524898afdf507448d2a8475aa50..edff0dc0c18f5ef204ca4d94695c8b33848aa018 100644 (file)
@@ -25,7 +25,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor;
 import org.sonar.api.config.Settings;
-import org.sonar.scanner.postjob.PostJobOptimizer;
+import org.sonar.api.config.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -39,7 +39,7 @@ public class PostJobOptimizerTest {
 
   @Before
   public void prepare() {
-    settings = new Settings();
+    settings = new MapSettings();
     optimizer = new PostJobOptimizer(settings);
   }
 
index d88135649a9c19918fd8a8702fe20719ee745b56..c79cef9cbaa959498cce6593a7784a4c2e67251f 100644 (file)
@@ -28,12 +28,12 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Project;
 import org.sonar.scanner.index.BatchComponentCache;
 import org.sonar.scanner.protocol.output.ScannerReport;
 import org.sonar.scanner.protocol.output.ScannerReportReader;
 import org.sonar.scanner.protocol.output.ScannerReportWriter;
-import org.sonar.scanner.report.MetadataPublisher;
 import org.sonar.scanner.rule.ModuleQProfiles;
 import org.sonar.scanner.rule.QProfile;
 import org.sonar.scanner.scan.ImmutableProjectReactor;
@@ -63,7 +63,7 @@ public class MetadataPublisherTest {
     org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php");
     componentCache.add(project, null);
     componentCache.add(sampleFile, project);
-    settings = new Settings();
+    settings = new MapSettings();
     qProfiles = mock(ModuleQProfiles.class);
     underTest = new MetadataPublisher(componentCache, new ImmutableProjectReactor(projectDef), settings, qProfiles);
   }
index 4f8dcd58f192a5a113e817d9bfc7d7e167535142..7ff2e9403b1d15c0c8ddccb77a0b1697c288767c 100644 (file)
@@ -32,6 +32,7 @@ import org.mockito.Mockito;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.platform.Server;
 import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.TempFolder;
@@ -40,9 +41,6 @@ import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.core.config.CorePropertyDefinitions;
 import org.sonar.scanner.analysis.DefaultAnalysisMode;
 import org.sonar.scanner.bootstrap.BatchWsClient;
-import org.sonar.scanner.report.AnalysisContextReportPublisher;
-import org.sonar.scanner.report.ReportPublisher;
-import org.sonar.scanner.report.ReportPublisherStep;
 import org.sonar.scanner.scan.ImmutableProjectReactor;
 
 import static org.apache.commons.io.FileUtils.readFileToString;
@@ -62,7 +60,7 @@ public class ReportPublisherTest {
   public ExpectedException exception = ExpectedException.none();
 
   DefaultAnalysisMode mode = mock(DefaultAnalysisMode.class);
-  Settings settings = new Settings(new PropertyDefinitions(CorePropertyDefinitions.all()));
+  Settings settings = new MapSettings(new PropertyDefinitions(CorePropertyDefinitions.all()));
   BatchWsClient wsClient = mock(BatchWsClient.class, Mockito.RETURNS_DEEP_STUBS);
   Server server = mock(Server.class);
   ImmutableProjectReactor reactor = mock(ImmutableProjectReactor.class);
index 00c9ea3d8dd51da32c3ab4e342b0ba9a2ed1ba14..aa12313ba2763cc0700d54ea814f2e7796dbe6ed 100644 (file)
@@ -27,10 +27,8 @@ import org.junit.rules.TemporaryFolder;
 import org.slf4j.Logger;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.rule.ModuleQProfiles;
-import org.sonar.scanner.rule.QProfile;
-import org.sonar.scanner.rule.QProfileVerifier;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -46,7 +44,7 @@ public class QProfileVerifierTest {
 
   private DefaultFileSystem fs;
   private ModuleQProfiles profiles;
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
 
   @Before
   public void before() throws Exception {
index 3dc3651276b5d9de7c7a18278760739b34e494e9..a15845f3afbc4fdf23eda644b3e5624270e5035d 100644 (file)
@@ -23,12 +23,9 @@ import java.util.Arrays;
 import org.junit.Test;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.profiles.RulesProfile;
 import org.sonar.api.rule.RuleKey;
-import org.sonar.scanner.rule.ModuleQProfiles;
-import org.sonar.scanner.rule.QProfile;
-import org.sonar.scanner.rule.RulesProfileProvider;
-import org.sonar.scanner.rule.RulesProfileWrapper;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
@@ -38,7 +35,7 @@ import static org.mockito.Mockito.when;
 public class RulesProfileProviderTest {
 
   ModuleQProfiles qProfiles = mock(ModuleQProfiles.class);
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   RulesProfileProvider provider = new RulesProfileProvider();
 
   @Test
index 652a7c106a70ff8c6b50c7a7e7be4421e113a82f..e4af7a57587b29afb93d2549c48b5ca5b43a65a1 100644 (file)
@@ -26,6 +26,7 @@ import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.internal.DefaultFileSystem;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.FakeJava;
@@ -42,7 +43,7 @@ public class LanguageVerifierTest {
   @Rule
   public ExpectedException thrown = ExpectedException.none();
 
-  private Settings settings = new Settings();
+  private Settings settings = new MapSettings();
   private LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(FakeJava.INSTANCE));
   private DefaultFileSystem fs;
 
index 05c1e9f5724ebbc7b6756b4c36661acfe49937b2..f779b0d80f4567932c6be17cfe5bf621cafb9bb0 100644 (file)
@@ -33,11 +33,13 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.analysis.DefaultAnalysisMode;
+import org.sonar.scanner.bootstrap.GlobalMode;
+import org.sonar.scanner.bootstrap.GlobalProperties;
 import org.sonar.scanner.bootstrap.GlobalSettings;
+import org.sonar.scanner.protocol.input.GlobalRepositories;
 import org.sonar.scanner.report.AnalysisContextReportPublisher;
 import org.sonar.scanner.repository.FileData;
 import org.sonar.scanner.repository.ProjectRepositories;
-import org.sonar.scanner.scan.ModuleSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -81,9 +83,7 @@ public class ModuleSettingsTest {
 
   @Test
   public void test_loading_of_module_settings() {
-    GlobalSettings globalSettings = mock(GlobalSettings.class);
-    when(globalSettings.getDefinitions()).thenReturn(new PropertyDefinitions());
-    when(globalSettings.getProperties()).thenReturn(ImmutableMap.of(
+    GlobalSettings globalSettings = newGlobalSettings(ImmutableMap.of(
       "overridding", "batch",
       "on-batch", "true"));
 
@@ -96,15 +96,12 @@ public class ModuleSettingsTest {
     assertThat(moduleSettings.getString("overridding")).isEqualTo("module");
     assertThat(moduleSettings.getString("on-batch")).isEqualTo("true");
     assertThat(moduleSettings.getString("on-module")).isEqualTo("true");
-
   }
 
   // SONAR-6386
   @Test
   public void test_loading_of_parent_module_settings_for_new_module() {
-    GlobalSettings globalSettings = mock(GlobalSettings.class);
-    when(globalSettings.getDefinitions()).thenReturn(new PropertyDefinitions());
-    when(globalSettings.getProperties()).thenReturn(ImmutableMap.of(
+    GlobalSettings globalSettings = newGlobalSettings(ImmutableMap.of(
       "overridding", "batch",
       "on-batch", "true"));
 
@@ -122,16 +119,14 @@ public class ModuleSettingsTest {
 
   @Test
   public void should_not_fail_when_accessing_secured_properties() {
-    GlobalSettings batchSettings = mock(GlobalSettings.class);
-    when(batchSettings.getDefinitions()).thenReturn(new PropertyDefinitions());
-    when(batchSettings.getProperties()).thenReturn(ImmutableMap.of(
+    GlobalSettings globalSettings = newGlobalSettings(ImmutableMap.of(
       "sonar.foo.secured", "bar"));
 
     ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2"));
 
     ProjectDefinition module = ProjectDefinition.create().setKey("struts-core");
 
-    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, projSettingsRepo, mode, mock(AnalysisContextReportPublisher.class));
+    ModuleSettings moduleSettings = new ModuleSettings(globalSettings, module, projSettingsRepo, mode, mock(AnalysisContextReportPublisher.class));
 
     assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
     assertThat(moduleSettings.getString("sonar.foo.secured")).isEqualTo("bar");
@@ -139,9 +134,7 @@ public class ModuleSettingsTest {
 
   @Test
   public void should_fail_when_accessing_secured_properties_in_issues() {
-    GlobalSettings batchSettings = mock(GlobalSettings.class);
-    when(batchSettings.getDefinitions()).thenReturn(new PropertyDefinitions());
-    when(batchSettings.getProperties()).thenReturn(ImmutableMap.of(
+    GlobalSettings globalSettings = newGlobalSettings(ImmutableMap.of(
       "sonar.foo.secured", "bar"));
 
     ProjectRepositories projSettingsRepo = createSettings("struts-core", ImmutableMap.of("sonar.foo.license.secured", "bar2"));
@@ -150,7 +143,7 @@ public class ModuleSettingsTest {
 
     ProjectDefinition module = ProjectDefinition.create().setKey("struts-core");
 
-    ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, projSettingsRepo, mode, mock(AnalysisContextReportPublisher.class));
+    ModuleSettings moduleSettings = new ModuleSettings(globalSettings, module, projSettingsRepo, mode, mock(AnalysisContextReportPublisher.class));
 
     assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
 
@@ -160,4 +153,10 @@ public class ModuleSettingsTest {
         "Access to the secured property 'sonar.foo.secured' is not possible in issues mode. The SonarQube plugin which requires this property must be deactivated in issues mode.");
     moduleSettings.getString("sonar.foo.secured");
   }
+
+  private GlobalSettings newGlobalSettings(Map<String, String> props) {
+    GlobalProperties globalProps = new GlobalProperties(props);
+    return new GlobalSettings(globalProps, new PropertyDefinitions(),
+      new GlobalRepositories(), new GlobalMode(globalProps));
+  }
 }
index 35648c6c72e8de1dca690195a07facfcb7ccd87f..9c9a24cc01d7f4dde09f3ffb1aabca11ef29beb8 100644 (file)
  */
 package org.sonar.scanner.scan;
 
-import static org.mockito.Mockito.when;
-
-import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.analysis.DefaultAnalysisMode;
-import org.sonar.scanner.scan.ProjectReactorValidator;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -32,8 +27,12 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.bootstrap.ProjectReactor;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.utils.MessageException;
+import org.sonar.scanner.analysis.DefaultAnalysisMode;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ProjectReactorValidatorTest {
 
@@ -47,7 +46,7 @@ public class ProjectReactorValidatorTest {
   @Before
   public void prepare() {
     mode = mock(DefaultAnalysisMode.class);
-    settings = new Settings();
+    settings = new MapSettings();
     validator = new ProjectReactorValidator(settings, mode);
   }
 
index e28b44a5f61a0e0e351f6533cfcc80131e8c0d45..5b889fb1340df1cc16d0170274f441783a240004 100644 (file)
@@ -40,7 +40,6 @@ import org.sonar.scanner.bootstrap.GlobalSettings;
 import org.sonar.scanner.protocol.input.GlobalRepositories;
 import org.sonar.scanner.repository.FileData;
 import org.sonar.scanner.repository.ProjectRepositories;
-import org.sonar.scanner.scan.ProjectSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -77,7 +76,7 @@ public class ProjectSettingsTest {
     project.setProperty("project.prop", "project");
 
     projectRef = new ProjectRepositories(emptySettings, emptyFileData, null);
-    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode);
+    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, projectRef, mode);
 
     assertThat(batchSettings.getString("project.prop")).isEqualTo("project");
   }
@@ -89,7 +88,7 @@ public class ProjectSettingsTest {
     settings.put("struts", "sonar.java.coveragePlugin", "jacoco");
 
     projectRef = new ProjectRepositories(settings, emptyFileData, null);
-    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode);
+    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, projectRef, mode);
     assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
   }
 
@@ -103,7 +102,7 @@ public class ProjectSettingsTest {
 
     projectRef = new ProjectRepositories(settings, emptyFileData, null);
 
-    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode);
+    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, projectRef, mode);
 
     assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco");
   }
@@ -115,7 +114,7 @@ public class ProjectSettingsTest {
     settings.put("struts", "sonar.foo.license.secured", "bar2");
 
     projectRef = new ProjectRepositories(settings, emptyFileData, null);
-    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode);
+    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, projectRef, mode);
 
     assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
     assertThat(batchSettings.getString("sonar.foo.secured")).isEqualTo("bar");
@@ -130,7 +129,7 @@ public class ProjectSettingsTest {
     when(mode.isIssues()).thenReturn(true);
 
     projectRef = new ProjectRepositories(settings, emptyFileData, null);
-    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, new PropertyDefinitions(), projectRef, mode);
+    ProjectSettings batchSettings = new ProjectSettings(new ProjectReactor(project), bootstrapProps, projectRef, mode);
 
     assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2");
     thrown.expect(MessageException.class);
index c084c7c78e8f1ee0fcc34722dcb7701a4182ae51..0007577b88c7fd008be4b3d597b6a5b16d678082 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.scanner.scan.filesystem;
 
+import java.io.File;
+import java.io.IOException;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
@@ -26,10 +28,8 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.scan.filesystem.FileExclusions;
-import org.sonar.scanner.scan.filesystem.ExclusionFilters;
-import java.io.File;
-import java.io.IOException;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -40,7 +40,7 @@ public class ExclusionFiltersTest {
 
   @Test
   public void no_inclusions_nor_exclusions() throws IOException {
-    ExclusionFilters filter = new ExclusionFilters(new FileExclusions(new Settings()));
+    ExclusionFilters filter = new ExclusionFilters(new FileExclusions(new MapSettings()));
     filter.prepare();
 
     java.io.File file = temp.newFile();
@@ -51,7 +51,7 @@ public class ExclusionFiltersTest {
 
   @Test
   public void match_inclusion() throws IOException {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.java");
     ExclusionFilters filter = new ExclusionFilters(new FileExclusions(settings));
     filter.prepare();
@@ -66,7 +66,7 @@ public class ExclusionFiltersTest {
 
   @Test
   public void match_at_least_one_inclusion() throws IOException {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.java,**/*Dto.java");
     ExclusionFilters filter = new ExclusionFilters(new FileExclusions(settings));
 
@@ -83,7 +83,7 @@ public class ExclusionFiltersTest {
 
   @Test
   public void match_exclusions() throws IOException {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "src/main/java/**/*");
     settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "src/test/java/**/*");
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.java");
@@ -108,7 +108,7 @@ public class ExclusionFiltersTest {
     File baseDir = temp.newFile();
     File excludedFile = new File(baseDir, "src/main/java/org/bar/Bar.java");
 
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "src/main/java/**/*");
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "file:" + excludedFile.getCanonicalPath());
     ExclusionFilters filter = new ExclusionFilters(new FileExclusions(settings));
@@ -124,7 +124,7 @@ public class ExclusionFiltersTest {
 
   @Test
   public void trim_pattern() {
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "   **/*Dao.java   ");
     ExclusionFilters filter = new ExclusionFilters(new FileExclusions(settings));
 
index 5dd278b89db015b3058108d3f3eabf1cf51017a4..c8346db929f1fe237a0005f1cb05ae40224187da 100644 (file)
@@ -23,13 +23,8 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.scanner.scan.filesystem.InputFileBuilder;
-import org.sonar.scanner.scan.filesystem.InputFileBuilderFactory;
-import org.sonar.scanner.scan.filesystem.LanguageDetectionFactory;
-import org.sonar.scanner.scan.filesystem.StatusDetectionFactory;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -43,7 +38,7 @@ public class InputFileBuilderFactoryTest {
     DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
 
     InputFileBuilderFactory factory = new InputFileBuilderFactory(ProjectDefinition.create().setKey("struts"), pathResolver, langDetectionFactory,
-      statusDetectionFactory, new Settings(), new FileMetadata());
+      statusDetectionFactory, new MapSettings(), new FileMetadata());
     InputFileBuilder builder = factory.create(fs);
 
     assertThat(builder.langDetection()).isNotNull();
index 0e496f4fe164f5f5677c71fbb67d8d4e136cd419..63fe01d8eb5b71b39b192b156dd9f9dbed8b144e 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.scanner.scan.filesystem;
 
+import java.io.File;
+import java.nio.charset.StandardCharsets;
 import org.apache.commons.io.FileUtils;
 import org.junit.Rule;
 import org.junit.Test;
@@ -26,15 +28,9 @@ import org.junit.rules.TemporaryFolder;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.FileMetadata;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.scan.filesystem.PathResolver;
 import org.sonar.api.utils.PathUtils;
-import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.scanner.scan.filesystem.InputFileBuilder;
-import org.sonar.scanner.scan.filesystem.LanguageDetection;
-import org.sonar.scanner.scan.filesystem.StatusDetection;
-import java.io.File;
-import java.nio.charset.StandardCharsets;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.any;
@@ -68,7 +64,7 @@ public class InputFileBuilderTest {
       .thenReturn(InputFile.Status.ADDED);
 
     InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
-      langDetection, statusDetection, fs, new Settings(), new FileMetadata());
+      langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
     DefaultInputFile inputFile = builder.create(srcFile);
     builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN);
 
@@ -91,7 +87,7 @@ public class InputFileBuilderTest {
     when(fs.baseDir()).thenReturn(basedir);
 
     InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
-      langDetection, statusDetection, fs, new Settings(), new FileMetadata());
+      langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
     DefaultInputFile inputFile = builder.create(srcFile);
 
     assertThat(inputFile).isNull();
@@ -111,7 +107,7 @@ public class InputFileBuilderTest {
     when(langDetection.language(any(InputFile.class))).thenReturn(null);
 
     InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(),
-      langDetection, statusDetection, fs, new Settings(), new FileMetadata());
+      langDetection, statusDetection, fs, new MapSettings(), new FileMetadata());
     DefaultInputFile inputFile = builder.create(srcFile);
     inputFile = builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN);
 
index 82c47c1aa0b875d04dfd92d0238e10632daf2459..0064dd10ebf7bc8aba834be9f601755b3f78accf 100644 (file)
 package org.sonar.scanner.scan.filesystem;
 
 import org.junit.Test;
-import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Languages;
 import org.sonar.scanner.FakeJava;
 import org.sonar.scanner.repository.language.DefaultLanguagesRepository;
 import org.sonar.scanner.repository.language.LanguagesRepository;
-import org.sonar.scanner.scan.filesystem.LanguageDetection;
-import org.sonar.scanner.scan.filesystem.LanguageDetectionFactory;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -34,7 +32,7 @@ public class LanguageDetectionFactoryTest {
   @Test
   public void testCreate() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(FakeJava.INSTANCE));
-    LanguageDetectionFactory factory = new LanguageDetectionFactory(new Settings(), languages);
+    LanguageDetectionFactory factory = new LanguageDetectionFactory(new MapSettings(), languages);
     LanguageDetection languageDetection = factory.create();
     assertThat(languageDetection).isNotNull();
     assertThat(languageDetection.patternsByLanguage()).hasSize(1);
index d5013ed0ba7964ea5f558754f74d90c0ce303286..16e66383578f6cc784c75bfcd59e29a2286fa3b2 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.scanner.scan.filesystem;
 
+import java.io.File;
+import java.io.IOException;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -27,14 +29,12 @@ import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.resources.Language;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.utils.MessageException;
 import org.sonar.scanner.repository.language.DefaultLanguagesRepository;
 import org.sonar.scanner.repository.language.LanguagesRepository;
-import org.sonar.scanner.scan.filesystem.LanguageDetection;
-import java.io.File;
-import java.io.IOException;
 
 import static junit.framework.Assert.fail;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -59,7 +59,7 @@ public class LanguageDetectionTest {
   @Test
   public void search_by_file_extension() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java", "jav"), new MockLanguage("cobol", "cbl", "cob")));
-    LanguageDetection detection = new LanguageDetection(new Settings(), languages);
+    LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
 
     assertThat(detection.language(newInputFile("Foo.java"))).isEqualTo("java");
     assertThat(detection.language(newInputFile("src/Foo.java"))).isEqualTo("java");
@@ -76,7 +76,7 @@ public class LanguageDetectionTest {
 
   @Test
   public void should_not_fail_if_no_language() throws Exception {
-    LanguageDetection detection = spy(new LanguageDetection(new Settings(), new DefaultLanguagesRepository(new Languages())));
+    LanguageDetection detection = spy(new LanguageDetection(new MapSettings(), new DefaultLanguagesRepository(new Languages())));
     assertThat(detection.language(newInputFile("Foo.java"))).isNull();
   }
 
@@ -84,7 +84,7 @@ public class LanguageDetectionTest {
   public void plugin_can_declare_a_file_extension_twice_for_case_sensitivity() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("abap", "abap", "ABAP")));
 
-    LanguageDetection detection = new LanguageDetection(new Settings(), languages);
+    LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
     assertThat(detection.language(newInputFile("abc.abap"))).isEqualTo("abap");
   }
 
@@ -95,12 +95,12 @@ public class LanguageDetectionTest {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java"), new MockLanguage("abap")));
 
     // No side-effect on non-ABAP projects
-    LanguageDetection detection = new LanguageDetection(new Settings(), languages);
+    LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
     assertThat(detection.language(newInputFile("abc"))).isNull();
     assertThat(detection.language(newInputFile("abc.abap"))).isNull();
     assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("java");
 
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "abap");
     detection = new LanguageDetection(settings, languages);
     assertThat(detection.language(newInputFile("abc"))).isEqualTo("abap");
@@ -112,7 +112,7 @@ public class LanguageDetectionTest {
   public void force_language_using_deprecated_property() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php")));
 
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "java");
     LanguageDetection detection = new LanguageDetection(settings, languages);
     assertThat(detection.language(newInputFile("abc"))).isNull();
@@ -127,7 +127,7 @@ public class LanguageDetectionTest {
     thrown.expectMessage("No language is installed with key 'unknown'. Please update property 'sonar.language'");
 
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php")));
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "unknown");
     new LanguageDetection(settings, languages);
   }
@@ -135,7 +135,7 @@ public class LanguageDetectionTest {
   @Test
   public void fail_if_conflicting_language_suffix() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml")));
-    LanguageDetection detection = new LanguageDetection(new Settings(), languages);
+    LanguageDetection detection = new LanguageDetection(new MapSettings(), languages);
     try {
       detection.language(newInputFile("abc.xhtml"));
       fail();
@@ -151,7 +151,7 @@ public class LanguageDetectionTest {
   public void solve_conflict_using_filepattern() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml")));
 
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("sonar.lang.patterns.xml", "xml/**");
     settings.setProperty("sonar.lang.patterns.web", "web/**");
     LanguageDetection detection = new LanguageDetection(settings, languages);
@@ -162,7 +162,7 @@ public class LanguageDetectionTest {
   @Test
   public void fail_if_conflicting_filepattern() throws Exception {
     LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("abap", "abap"), new MockLanguage("cobol", "cobol")));
-    Settings settings = new Settings();
+    Settings settings = new MapSettings();
     settings.setProperty("sonar.lang.patterns.abap", "*.abap,*.txt");
     settings.setProperty("sonar.lang.patterns.cobol", "*.cobol,*.txt");
 
index ba0bd7ff7c775d7e88789852a660b8f146cf81a3..227934bc39f2d096896fb029b572a76a5c29bc32 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.scanner.scan.report;
 
+import java.util.Arrays;
+import java.util.Collections;
 import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
@@ -26,14 +28,12 @@ import org.junit.Test;
 import org.sonar.api.batch.fs.InputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.utils.log.LogTester;
 import org.sonar.scanner.issue.IssueCache;
 import org.sonar.scanner.issue.tracking.TrackedIssue;
 import org.sonar.scanner.scan.filesystem.InputPathCache;
-import org.sonar.scanner.scan.report.ConsoleReport;
-import java.util.Arrays;
-import java.util.Collections;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -51,7 +51,7 @@ public class ConsoleReportTest {
 
   @Before
   public void prepare() {
-    settings = new Settings();
+    settings = new MapSettings();
     issueCache = mock(IssueCache.class);
     inputPathCache = mock(InputPathCache.class);
     report = new ConsoleReport(settings, issueCache, inputPathCache);
index c8f8bef41138d98bb92bc3de3363c6214a83746b..e7109daa410f0a066c248db20f404467c14e26eb 100644 (file)
@@ -39,6 +39,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.rule.Rules;
 import org.sonar.api.batch.rule.internal.RulesBuilder;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.platform.Server;
 import org.sonar.api.resources.Project;
@@ -49,7 +50,6 @@ import org.sonar.scanner.issue.tracking.TrackedIssue;
 import org.sonar.scanner.protocol.input.ScannerInput;
 import org.sonar.scanner.repository.user.UserRepositoryLoader;
 import org.sonar.scanner.scan.filesystem.InputPathCache;
-import org.sonar.scanner.scan.report.JSONReport;
 
 import static net.javacrumbs.jsonunit.assertj.JsonAssert.assertThatJson;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -69,7 +69,7 @@ public class JSONReportTest {
   DefaultFileSystem fs;
   Server server = mock(Server.class);
   Rules rules = mock(Rules.class);
-  Settings settings = new Settings();
+  Settings settings = new MapSettings();
   IssueCache issueCache = mock(IssueCache.class);
   private UserRepositoryLoader userRepository;
 
index a5eace1c5374d80584a69d389f8fd856a8fc8b63..8c32a380fde2484c0fe5b98f023a4f300c1fb691 100644 (file)
@@ -34,6 +34,7 @@ import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.sensor.internal.SensorStorage;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.internal.SonarRuntimeImpl;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.utils.Version;
@@ -65,7 +66,7 @@ public class DefaultSensorContextTest {
     MetricFinder metricFinder = mock(MetricFinder.class);
     when(metricFinder.<Integer>findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
     when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
-    settings = new Settings();
+    settings = new MapSettings();
     sensorStorage = mock(SensorStorage.class);
     analysisMode = mock(AnalysisMode.class);
     runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER);
index c0d8053ece5b58a08dcf6c0ef9de9dae1ff029bd..e9ae12fd68819f59a0d925a9f79b25c6d41907aa 100644 (file)
@@ -33,6 +33,7 @@ import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
 import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
 import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.resources.File;
@@ -75,7 +76,7 @@ public class DefaultSensorStorageTest {
     MetricFinder metricFinder = mock(MetricFinder.class);
     when(metricFinder.<Integer>findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
     when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
-    settings = new Settings();
+    settings = new MapSettings();
     moduleIssues = mock(ModuleIssues.class);
     project = new Project("myProject");
     measureCache = mock(MeasureCache.class);
index 582ba2576fbb3505f179da2b6ae2a03d35770d7d..3fac6d4f0e8cb05b13e7bb04a2fac02ec3672163 100644 (file)
@@ -31,8 +31,8 @@ import org.sonar.api.batch.rule.ActiveRules;
 import org.sonar.api.batch.rule.internal.ActiveRulesBuilder;
 import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.rule.RuleKey;
-import org.sonar.scanner.sensor.SensorOptimizer;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -51,7 +51,7 @@ public class SensorOptimizerTest {
   @Before
   public void prepare() throws Exception {
     fs = new DefaultFileSystem(temp.newFolder().toPath());
-    settings = new Settings();
+    settings = new MapSettings();
     optimizer = new SensorOptimizer(fs, new ActiveRulesBuilder().build(), settings);
   }
 
index b2238fe214a97a4669ccf11a47413c7c097fbba5..3a59eecdce310004c0b531ccefe631b37463631e 100644 (file)
  */
 package org.sonar.scanner.sensor.coverage;
 
-import org.junit.rules.TemporaryFolder;
-
-import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import com.google.common.collect.ImmutableMap;
+import java.util.Map;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
+import org.sonar.api.config.MapSettings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.api.measures.Measure;
 import org.sonar.api.resources.File;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.core.config.ExclusionProperties;
-import org.sonar.scanner.sensor.coverage.CoverageExclusions;
-import java.util.Map;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
@@ -58,7 +57,7 @@ public class CoverageExclusionsTest {
 
   @Before
   public void createFilter() {
-    settings = new Settings(new PropertyDefinitions(ExclusionProperties.all()));
+    settings = new MapSettings(new PropertyDefinitions(ExclusionProperties.all()));
     fs = new DefaultFileSystem(temp.getRoot());
     filter = new CoverageExclusions(settings, fs);
   }
index c2f2f0aeb58ea4e0cff5fad644bd07edcfad3fd4..9f50909105cfab279b861d769632db0904394045 100644 (file)
@@ -30,7 +30,6 @@ import org.sonar.api.resources.Resource;
 import org.sonar.api.source.Symbolizable;
 import org.sonar.scanner.index.BatchComponent;
 import org.sonar.scanner.sensor.DefaultSensorStorage;
-import org.sonar.scanner.source.SymbolizableBuilder;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;