diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2015-10-06 17:36:39 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2015-10-07 00:02:09 +0200 |
commit | 42b27a86a33b63b0f72ff37c289ca7e41473ed7a (patch) | |
tree | 5763fe3e27ade8cb64d4a8e0a17312442cca8d78 | |
parent | 28ae34bded6c22fabbcbabbd3fb49b923cf02dac (diff) | |
download | sonarqube-42b27a86a33b63b0f72ff37c289ca7e41473ed7a.tar.gz sonarqube-42b27a86a33b63b0f72ff37c289ca7e41473ed7a.zip |
SONAR-6837 Allow to configure WS read timeout from batch
14 files changed, 249 insertions, 214 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/analysis/AnalysisWSLoaderProvider.java b/sonar-batch/src/main/java/org/sonar/batch/analysis/AnalysisWSLoaderProvider.java index dc91e97a2be..ca0f521d42e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/analysis/AnalysisWSLoaderProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/analysis/AnalysisWSLoaderProvider.java @@ -19,15 +19,12 @@ */ package org.sonar.batch.analysis; -import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.picocontainer.injectors.ProviderAdapter; - -import java.util.Map; - +import org.sonar.api.batch.AnalysisMode; import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.cache.WSLoader; +import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.sonar.home.cache.PersistentCache; -import org.sonar.api.batch.AnalysisMode; public class AnalysisWSLoaderProvider extends ProviderAdapter { private WSLoader wsLoader; @@ -36,12 +33,12 @@ public class AnalysisWSLoaderProvider extends ProviderAdapter { if (wsLoader == null) { // recreate cache directory if needed for this analysis cache.reconfigure(); - wsLoader = new WSLoader(getStrategy(props.properties(), mode), cache, client); + wsLoader = new WSLoader(getStrategy(mode), cache, client, props); } return wsLoader; } - private static LoadStrategy getStrategy(Map<String, String> props, AnalysisMode mode) { + private static LoadStrategy getStrategy(AnalysisMode mode) { if (mode.isIssues()) { return LoadStrategy.CACHE_ONLY; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java index 3516932cd50..9df2d26f876 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java @@ -44,9 +44,6 @@ import org.sonar.batch.platform.DefaultServer; import org.sonar.batch.repository.DefaultGlobalRepositoriesLoader; import org.sonar.batch.repository.GlobalRepositoriesLoader; import org.sonar.batch.repository.GlobalRepositoriesProvider; -import org.sonar.batch.rule.DefaultRulesLoader; -import org.sonar.batch.rule.RulesLoader; -import org.sonar.batch.rule.RulesProvider; import org.sonar.batch.scan.ProjectScanContainer; import org.sonar.core.platform.ComponentContainer; import org.sonar.core.platform.PluginClassloaderFactory; @@ -109,7 +106,6 @@ public class GlobalContainer extends ComponentContainer { CachesManager.class, GlobalSettings.class, - new RulesProvider(), ServerClient.class, DefaultServer.class, new GlobalTempFolderProvider(), @@ -121,7 +117,6 @@ public class GlobalContainer extends ComponentContainer { new GlobalRepositoriesProvider(), UuidFactoryImpl.INSTANCE); addIfMissing(BatchPluginInstaller.class, PluginInstaller.class); - addIfMissing(DefaultRulesLoader.class, RulesLoader.class); addIfMissing(DefaultGlobalRepositoriesLoader.class, GlobalRepositoriesLoader.class); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java index 0b834e8b4d5..3487247ae2b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectCacheSynchronizer.java @@ -146,6 +146,7 @@ public class ProjectCacheSynchronizer { for (String k : keys) { activeRulesLoader.load(k, null); } + profiler.stopInfo(); if (projectRepo.lastAnalysisDate() != null) { profiler.startInfo("Load server issues"); diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java index 2bfc9dd12fa..0bf59d119ee 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/ProjectSyncContainer.java @@ -19,26 +19,25 @@ */ package org.sonar.batch.cache; -import javax.annotation.Nullable; - -import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.api.CoreProperties; - import java.util.HashMap; import java.util.Map; - +import javax.annotation.Nullable; +import org.sonar.api.CoreProperties; import org.sonar.batch.analysis.AnalysisProperties; +import org.sonar.batch.analysis.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalProperties; +import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; -import org.sonar.batch.rule.ActiveRulesLoader; -import org.sonar.batch.rule.DefaultActiveRulesLoader; -import org.sonar.batch.repository.QualityProfileLoader; import org.sonar.batch.repository.DefaultQualityProfileLoader; -import org.sonar.batch.cache.WSLoader.LoadStrategy; -import org.sonar.batch.repository.user.UserRepositoryLoader; import org.sonar.batch.repository.DefaultServerIssuesLoader; import org.sonar.batch.repository.ProjectRepositoriesLoader; +import org.sonar.batch.repository.QualityProfileLoader; import org.sonar.batch.repository.ServerIssuesLoader; +import org.sonar.batch.repository.user.UserRepositoryLoader; +import org.sonar.batch.rule.ActiveRulesLoader; +import org.sonar.batch.rule.DefaultActiveRulesLoader; +import org.sonar.batch.rule.DefaultRulesLoader; +import org.sonar.batch.rule.RulesLoader; import org.sonar.core.platform.ComponentContainer; public class ProjectSyncContainer extends ComponentContainer { @@ -88,6 +87,7 @@ public class ProjectSyncContainer extends ComponentContainer { addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class); addIfMissing(DefaultServerIssuesLoader.class, ServerIssuesLoader.class); addIfMissing(DefaultQualityProfileLoader.class, QualityProfileLoader.class); + addIfMissing(DefaultRulesLoader.class, RulesLoader.class); addIfMissing(DefaultActiveRulesLoader.class, ActiveRulesLoader.class); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java b/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java index ecd7ef8f405..e64015db867 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/StrategyWSLoaderProvider.java @@ -19,10 +19,10 @@ */ package org.sonar.batch.cache; -import org.sonar.batch.cache.WSLoader.LoadStrategy; - import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.batch.bootstrap.GlobalProperties; import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.sonar.home.cache.PersistentCache; public class StrategyWSLoaderProvider extends ProviderAdapter { @@ -33,9 +33,9 @@ public class StrategyWSLoaderProvider extends ProviderAdapter { this.strategy = strategy; } - public WSLoader provide(PersistentCache cache, ServerClient client) { + public WSLoader provide(PersistentCache cache, ServerClient client, GlobalProperties globalProps) { if (wsLoader == null) { - wsLoader = new WSLoader(strategy, cache, client); + wsLoader = new WSLoader(strategy, cache, client, globalProps); } return wsLoader; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java b/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java index a430a3ce93e..5845469dcf9 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/cache/WSLoader.java @@ -19,29 +19,29 @@ */ package org.sonar.batch.cache; -import org.sonar.api.utils.HttpDownloader.HttpException; - import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; - import javax.annotation.Nonnull; import javax.annotation.Nullable; - import org.apache.commons.io.IOUtils; +import org.sonar.api.utils.HttpDownloader.HttpException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.bootstrap.UserProperties; import org.sonar.home.cache.PersistentCache; + import static org.sonar.batch.cache.WSLoader.ServerStatus.ACCESSIBLE; import static org.sonar.batch.cache.WSLoader.ServerStatus.NOT_ACCESSIBLE; import static org.sonar.batch.cache.WSLoader.ServerStatus.UNKNOWN; public class WSLoader { + static final String SONAR_WS_TIMEOUT_PROPS = "sonar.ws.timeout"; private static final Logger LOG = Loggers.get(WSLoader.class); private static final String FAIL_MSG = "Server is not accessible and data is not cached"; private static final int CONNECT_TIMEOUT = 5_000; - private static final int READ_TIMEOUT = 600_000; + private static final int DEFAULT_READ_TIMEOUT = 60_000; private static final String REQUEST_METHOD = "GET"; public enum ServerStatus { @@ -55,15 +55,76 @@ public class WSLoader { private final LoadStrategy defautLoadStrategy; private final ServerClient client; private final PersistentCache cache; + private final UserProperties userProperties; private ServerStatus serverStatus; - public WSLoader(LoadStrategy strategy, PersistentCache cache, ServerClient client) { + private DataLoader<String> stringServerLoader = new DataLoader<String>() { + @Override + public String load(String id) throws IOException { + InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, getReadTimeout()); + String str = IOUtils.toString(is, StandardCharsets.UTF_8); + try { + cache.put(id, str.getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + throw new IllegalStateException("Error saving to WS cache", e); + } + return str; + } + + }; + + private DataLoader<String> stringCacheLoader = new DataLoader<String>() { + @Override + public String load(String id) throws IOException { + return cache.getString(id); + } + }; + + private DataLoader<InputStream> streamServerLoader = new DataLoader<InputStream>() { + @Override + public InputStream load(String id) throws IOException { + InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, getReadTimeout()); + try { + cache.put(id, is); + } catch (IOException e) { + throw new IllegalStateException("Error saving to WS cache", e); + } + is.close(); + return cache.getStream(id); + } + }; + + private DataLoader<InputStream> streamCacheLoader = new DataLoader<InputStream>() { + @Override + public InputStream load(String id) throws IOException { + return cache.getStream(id); + } + }; + + private class NotAvailableException extends Exception { + private static final long serialVersionUID = 1L; + + public NotAvailableException(String message) { + super(message); + } + + public NotAvailableException(Throwable cause) { + super(cause); + } + } + + public WSLoader(LoadStrategy strategy, PersistentCache cache, ServerClient client, UserProperties settings) { this.defautLoadStrategy = strategy; + this.userProperties = settings; this.serverStatus = UNKNOWN; this.cache = cache; this.client = client; } + private int getReadTimeout() { + return userProperties.properties().containsKey(SONAR_WS_TIMEOUT_PROPS) ? Integer.parseInt(userProperties.property(SONAR_WS_TIMEOUT_PROPS)) * 1000 : DEFAULT_READ_TIMEOUT; + } + @Nonnull public WSLoaderResult<InputStream> loadStream(String id) { return load(id, defautLoadStrategy, streamServerLoader, streamCacheLoader); @@ -185,57 +246,4 @@ public class WSLoader { } } - private DataLoader<String> stringServerLoader = new DataLoader<String>() { - @Override - public String load(String id) throws IOException { - InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, READ_TIMEOUT); - String str = IOUtils.toString(is, StandardCharsets.UTF_8); - try { - cache.put(id, str.getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - throw new IllegalStateException("Error saving to WS cache", e); - } - return str; - } - }; - - private DataLoader<String> stringCacheLoader = new DataLoader<String>() { - @Override - public String load(String id) throws IOException { - return cache.getString(id); - } - }; - - private DataLoader<InputStream> streamServerLoader = new DataLoader<InputStream>() { - @Override - public InputStream load(String id) throws IOException { - InputStream is = client.load(id, REQUEST_METHOD, true, CONNECT_TIMEOUT, READ_TIMEOUT); - try { - cache.put(id, is); - } catch (IOException e) { - throw new IllegalStateException("Error saving to WS cache", e); - } - is.close(); - return cache.getStream(id); - } - }; - - private DataLoader<InputStream> streamCacheLoader = new DataLoader<InputStream>() { - @Override - public InputStream load(String id) throws IOException { - return cache.getStream(id); - } - }; - - private class NotAvailableException extends Exception { - private static final long serialVersionUID = 1L; - - public NotAvailableException(String message) { - super(message); - } - - public NotAvailableException(Throwable cause) { - super(cause); - } - } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java index da9f5211994..3c96cf3ea63 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/ActiveRulesProvider.java @@ -19,22 +19,21 @@ */ package org.sonar.batch.rule; -import org.sonar.api.utils.log.Profiler; - -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.picocontainer.injectors.ProviderAdapter; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; -import org.sonar.api.batch.rule.internal.NewActiveRule; -import org.sonar.api.rule.RuleKey; - import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.lang.mutable.MutableBoolean; +import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; +import org.sonar.api.batch.rule.internal.NewActiveRule; +import org.sonar.api.rule.RuleKey; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.api.utils.log.Profiler; /** * Loads the rules that are activated on the Quality profiles @@ -48,13 +47,14 @@ public class ActiveRulesProvider extends ProviderAdapter { public ActiveRules provide(ActiveRulesLoader loader, ModuleQProfiles qProfiles) { if (singleton == null) { Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); - singleton = load(loader, qProfiles); - profiler.stopInfo(); + MutableBoolean fromCache = new MutableBoolean(); + singleton = load(loader, qProfiles, fromCache); + profiler.stopInfo(fromCache.booleanValue()); } return singleton; } - private static ActiveRules load(ActiveRulesLoader loader, ModuleQProfiles qProfiles) { + private static ActiveRules load(ActiveRulesLoader loader, ModuleQProfiles qProfiles, MutableBoolean fromCache) { Collection<String> qProfileKeys = getKeys(qProfiles); Map<RuleKey, LoadedActiveRule> loadedRulesByKey = new HashMap<>(); @@ -62,7 +62,7 @@ public class ActiveRulesProvider extends ProviderAdapter { try { for (String qProfileKey : qProfileKeys) { Collection<LoadedActiveRule> qProfileRules; - qProfileRules = load(loader, qProfileKey); + qProfileRules = load(loader, qProfileKey, fromCache); for (LoadedActiveRule r : qProfileRules) { if (!loadedRulesByKey.containsKey(r.getRuleKey())) { @@ -100,8 +100,8 @@ public class ActiveRulesProvider extends ProviderAdapter { return builder.build(); } - private static List<LoadedActiveRule> load(ActiveRulesLoader loader, String qProfileKey) throws IOException { - return loader.load(qProfileKey, null); + private static List<LoadedActiveRule> load(ActiveRulesLoader loader, String qProfileKey, MutableBoolean fromCache) throws IOException { + return loader.load(qProfileKey, fromCache); } private static Collection<String> getKeys(ModuleQProfiles qProfiles) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java index 6c63e451f45..373364dd944 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/rule/DefaultActiveRulesLoader.java @@ -64,6 +64,9 @@ public class DefaultActiveRulesLoader implements ActiveRulesLoader { break; } page++; + if (fromCache != null) { + fromCache.setValue(result.isFromCache()); + } } return ruleList; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index b882d231243..7b605d2b9b0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -19,29 +19,6 @@ */ package org.sonar.batch.scan; -import org.sonar.batch.repository.ProjectRepositoriesProvider; - -import org.sonar.batch.repository.ProjectRepositories; -import org.sonar.batch.cache.ProjectPersistentCacheProvider; -import org.sonar.batch.issue.tracking.LocalIssueTracking; -import org.sonar.batch.issue.tracking.IssueTransition; -import org.sonar.batch.repository.QualityProfileProvider; -import org.sonar.batch.repository.DefaultQualityProfileLoader; -import org.sonar.batch.repository.QualityProfileLoader; -import org.sonar.batch.rule.DefaultActiveRulesLoader; -import org.sonar.batch.rule.ActiveRulesLoader; -import org.sonar.batch.analysis.DefaultAnalysisMode; -import org.sonar.batch.analysis.AnalysisWSLoaderProvider; -import org.sonar.batch.analysis.AnalysisTempFolderProvider; -import org.sonar.batch.analysis.AnalysisProperties; -import org.sonar.batch.repository.user.UserRepositoryLoader; -import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader; -import org.sonar.batch.issue.tracking.ServerLineHashesLoader; -import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; -import org.sonar.batch.repository.DefaultServerIssuesLoader; -import org.sonar.batch.repository.ProjectRepositoriesLoader; -import org.sonar.batch.repository.ServerIssuesLoader; -import org.sonar.batch.issue.DefaultIssueCallback; import com.google.common.annotations.VisibleForTesting; import org.sonar.api.CoreProperties; import org.sonar.api.batch.InstantiationStrategy; @@ -55,18 +32,28 @@ import org.sonar.api.utils.log.Loggers; import org.sonar.batch.DefaultFileLinesContextFactory; import org.sonar.batch.DefaultProjectTree; import org.sonar.batch.ProjectConfigurator; +import org.sonar.batch.analysis.AnalysisProperties; +import org.sonar.batch.analysis.AnalysisTempFolderProvider; +import org.sonar.batch.analysis.AnalysisWSLoaderProvider; +import org.sonar.batch.analysis.DefaultAnalysisMode; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; import org.sonar.batch.bootstrap.MetricProvider; +import org.sonar.batch.cache.ProjectPersistentCacheProvider; import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.events.EventBus; import org.sonar.batch.index.BatchComponentCache; import org.sonar.batch.index.Caches; import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.issue.DefaultIssueCallback; import org.sonar.batch.issue.DefaultProjectIssues; import org.sonar.batch.issue.IssueCache; +import org.sonar.batch.issue.tracking.DefaultServerLineHashesLoader; +import org.sonar.batch.issue.tracking.IssueTransition; +import org.sonar.batch.issue.tracking.LocalIssueTracking; import org.sonar.batch.issue.tracking.ServerIssueRepository; +import org.sonar.batch.issue.tracking.ServerLineHashesLoader; import org.sonar.batch.mediumtest.ScanTaskObservers; import org.sonar.batch.phases.PhasesTimeProfiler; import org.sonar.batch.profiling.PhasesSumUpTimeProfiler; @@ -80,8 +67,23 @@ import org.sonar.batch.report.MetadataPublisher; import org.sonar.batch.report.ReportPublisher; import org.sonar.batch.report.SourcePublisher; import org.sonar.batch.report.TestExecutionAndCoveragePublisher; +import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; +import org.sonar.batch.repository.DefaultQualityProfileLoader; +import org.sonar.batch.repository.DefaultServerIssuesLoader; +import org.sonar.batch.repository.ProjectRepositories; +import org.sonar.batch.repository.ProjectRepositoriesLoader; +import org.sonar.batch.repository.ProjectRepositoriesProvider; +import org.sonar.batch.repository.QualityProfileLoader; +import org.sonar.batch.repository.QualityProfileProvider; +import org.sonar.batch.repository.ServerIssuesLoader; import org.sonar.batch.repository.language.DefaultLanguagesRepository; +import org.sonar.batch.repository.user.UserRepositoryLoader; +import org.sonar.batch.rule.ActiveRulesLoader; import org.sonar.batch.rule.ActiveRulesProvider; +import org.sonar.batch.rule.DefaultActiveRulesLoader; +import org.sonar.batch.rule.DefaultRulesLoader; +import org.sonar.batch.rule.RulesLoader; +import org.sonar.batch.rule.RulesProvider; import org.sonar.batch.scan.filesystem.InputPathCache; import org.sonar.batch.scan.measure.DefaultMetricFinder; import org.sonar.batch.scan.measure.DeprecatedMetricFinder; @@ -148,6 +150,7 @@ public class ProjectScanContainer extends ComponentContainer { Caches.class, BatchComponentCache.class, DefaultIssueCallback.class, + new RulesProvider(), new ProjectRepositoriesProvider(), new ProjectPersistentCacheProvider(), @@ -205,6 +208,7 @@ public class ProjectScanContainer extends ComponentContainer { ScanTaskObservers.class, UserRepositoryLoader.class); + addIfMissing(DefaultRulesLoader.class, RulesLoader.class); addIfMissing(DefaultActiveRulesLoader.class, ActiveRulesLoader.class); addIfMissing(DefaultQualityProfileLoader.class, QualityProfileLoader.class); addIfMissing(DefaultProjectRepositoriesLoader.class, ProjectRepositoriesLoader.class); diff --git a/sonar-batch/src/test/java/org/sonar/batch/analysis/AnalysisWSLoaderProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/analysis/AnalysisWSLoaderProviderTest.java index 9e80507094b..7624edf7b28 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/analysis/AnalysisWSLoaderProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/analysis/AnalysisWSLoaderProviderTest.java @@ -19,22 +19,18 @@ */ package org.sonar.batch.analysis; -import org.sonar.batch.analysis.AnalysisWSLoaderProvider; - -import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.cache.WSLoader.LoadStrategy; -import org.sonar.batch.analysis.AnalysisProperties; -import org.sonar.api.batch.AnalysisMode; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.sonar.api.batch.AnalysisMode; import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.cache.WSLoader; +import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.sonar.home.cache.PersistentCache; -import java.util.HashMap; -import java.util.Map; - import static org.assertj.core.api.Assertions.assertThat; public class AnalysisWSLoaderProviderTest { diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/StrategyWSLoaderProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/StrategyWSLoaderProviderTest.java index a7c613056bf..5d9ed445822 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/StrategyWSLoaderProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/StrategyWSLoaderProviderTest.java @@ -19,16 +19,17 @@ */ package org.sonar.batch.cache; -import static org.assertj.core.api.Assertions.assertThat; - -import org.sonar.batch.cache.WSLoader.LoadStrategy; - import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.sonar.batch.bootstrap.GlobalProperties; import org.sonar.batch.bootstrap.ServerClient; -import org.mockito.Mock; +import org.sonar.batch.cache.WSLoader.LoadStrategy; import org.sonar.home.cache.PersistentCache; -import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; public class StrategyWSLoaderProviderTest { @Mock @@ -37,15 +38,18 @@ public class StrategyWSLoaderProviderTest { @Mock private ServerClient client; + private GlobalProperties globalProps; + @Before public void setUp() { MockitoAnnotations.initMocks(this); + globalProps = mock(GlobalProperties.class); } @Test public void testStrategy() { StrategyWSLoaderProvider provider = new StrategyWSLoaderProvider(LoadStrategy.CACHE_FIRST); - WSLoader wsLoader = provider.provide(cache, client); + WSLoader wsLoader = provider.provide(cache, client, globalProps); assertThat(wsLoader.getDefaultStrategy()).isEqualTo(LoadStrategy.CACHE_FIRST); } @@ -53,8 +57,8 @@ public class StrategyWSLoaderProviderTest { @Test public void testSingleton() { StrategyWSLoaderProvider provider = new StrategyWSLoaderProvider(LoadStrategy.CACHE_FIRST); - WSLoader wsLoader = provider.provide(cache, client); + WSLoader wsLoader = provider.provide(cache, client, globalProps); - assertThat(provider.provide(null, null)).isEqualTo(wsLoader); + assertThat(provider.provide(null, null, null)).isEqualTo(wsLoader); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderTest.java index db9fe132fa9..c75259b5b36 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderTest.java @@ -19,39 +19,39 @@ */ package org.sonar.batch.cache; -import org.sonar.batch.bootstrap.ServerClient; -import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.cache.WSLoader.LoadStrategy; +import com.google.common.collect.ImmutableMap; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import org.apache.commons.io.IOUtils; import org.hamcrest.Matchers; -import org.junit.rules.ExpectedException; +import org.junit.Before; import org.junit.Rule; -import org.sonar.api.utils.HttpDownloader; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import org.apache.commons.io.IOUtils; -import org.mockito.Mockito; -import org.mockito.InOrder; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; +import org.sonar.api.utils.HttpDownloader; +import org.sonar.batch.bootstrap.ServerClient; +import org.sonar.batch.bootstrap.UserProperties; +import org.sonar.batch.cache.WSLoader.LoadStrategy; +import org.sonar.home.cache.PersistentCache; -import static org.junit.Assert.*; -import static org.mockito.Mockito.mock; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.anyInt; -import org.junit.Test; -import org.mockito.MockitoAnnotations; -import org.junit.Before; -import org.sonar.home.cache.PersistentCache; -import org.mockito.Mock; public class WSLoaderTest { private final static String ID = "dummy"; @@ -64,6 +64,7 @@ public class WSLoaderTest { private PersistentCache cache; @Rule public ExpectedException exception = ExpectedException.none(); + private UserProperties props; @Before public void setUp() throws IOException { @@ -76,12 +77,13 @@ public class WSLoaderTest { return new URI((String) invocation.getArguments()[0]); } }); + props = mock(UserProperties.class); } @Test public void dont_retry_server_offline() throws IOException { turnServerOffline(); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); assertResult(loader.loadString(ID), cacheValue, true); assertResult(loader.loadString(ID), cacheValue, true); @@ -94,7 +96,7 @@ public class WSLoaderTest { public void get_stream_from_cache() throws IOException { InputStream is = mock(InputStream.class); when(cache.getStream(ID)).thenReturn(is); - WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client, props); WSLoaderResult<InputStream> result = loader.loadStream(ID); assertThat(result.get()).isEqualTo(is); verify(cache).getStream(ID); @@ -110,7 +112,7 @@ public class WSLoaderTest { when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenReturn(is1); when(cache.getStream(ID)).thenReturn(is2); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); WSLoaderResult<InputStream> result = loader.loadStream(ID); assertThat(result.get()).isEqualTo(is2); @@ -122,9 +124,31 @@ public class WSLoaderTest { } @Test + public void default_timeout() throws IOException { + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); + loader.loadStream(ID); + + verify(client).load(anyString(), anyString(), anyBoolean(), anyInt(), eq(60_000)); + + verifyNoMoreInteractions(client); + } + + @Test + public void change_timeout() throws IOException { + when(props.properties()).thenReturn(ImmutableMap.of(WSLoader.SONAR_WS_TIMEOUT_PROPS, "20")); + when(props.property(WSLoader.SONAR_WS_TIMEOUT_PROPS)).thenReturn("20"); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); + loader.loadStream(ID); + + verify(client).load(anyString(), anyString(), anyBoolean(), anyInt(), eq(20_000)); + + verifyNoMoreInteractions(client); + } + + @Test public void test_cache_strategy_fallback() throws IOException { turnCacheEmpty(); - WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client, props); assertResult(loader.loadString(ID), serverValue, false); @@ -136,7 +160,7 @@ public class WSLoaderTest { @Test public void test_server_strategy_fallback() throws IOException { turnServerOffline(); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); assertResult(loader.loadString(ID), cacheValue, true); @@ -147,7 +171,7 @@ public class WSLoaderTest { @Test public void test_put_cache() throws IOException { - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); loader.loadString(ID); verify(cache).put(ID, serverValue.getBytes()); } @@ -157,7 +181,7 @@ public class WSLoaderTest { turnServerOffline(); when(cache.getString(ID)).thenThrow(new NullPointerException()); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); try { loader.loadString(ID); @@ -172,7 +196,7 @@ public class WSLoaderTest { public void test_throw_cache_exception() throws IOException { when(cache.getString(ID)).thenThrow(new IllegalStateException()); - WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client, props); try { loader.loadString(ID); @@ -190,7 +214,7 @@ public class WSLoaderTest { when(client.load(anyString(), anyString(), anyBoolean(), anyInt(), anyInt())).thenThrow(wrapperException); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); try { loader.loadString(ID); @@ -208,7 +232,7 @@ public class WSLoaderTest { exception.expect(IllegalStateException.class); exception.expectMessage(Matchers.is("Server is not available")); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client, props); loader.loadString(ID); } @@ -220,7 +244,7 @@ public class WSLoaderTest { exception.expect(IllegalStateException.class); exception.expectMessage(Matchers.is("Server is not accessible and data is not cached")); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); loader.loadString(ID); } @@ -231,13 +255,13 @@ public class WSLoaderTest { exception.expect(IllegalStateException.class); exception.expectMessage(Matchers.is("Data is not cached")); - WSLoader loader = new WSLoader(LoadStrategy.CACHE_ONLY, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.CACHE_ONLY, cache, client, props); loader.loadString(ID); } @Test public void test_server_strategy() throws IOException { - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); assertResult(loader.loadString(ID), serverValue, false); // should not fetch from cache @@ -248,13 +272,13 @@ public class WSLoaderTest { @Test(expected = IllegalStateException.class) public void test_server_only() throws IOException { turnServerOffline(); - WSLoader loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client, props); loader.loadString(ID); } @Test public void test_string() { - WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + WSLoader loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, props); assertResult(loader.loadString(ID), serverValue, false); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderTestWithServer.java b/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderWithServerTest.java index def5566c274..cd5b2e3b052 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderTestWithServer.java +++ b/sonar-batch/src/test/java/org/sonar/batch/cache/WSLoaderWithServerTest.java @@ -19,27 +19,27 @@ */ package org.sonar.batch.cache; -import static org.mockito.Mockito.mock; - -import org.sonar.home.cache.TTLCacheInvalidation; - +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.sonar.batch.bootstrap.GlobalProperties; import org.sonar.batch.bootstrap.MockHttpServer; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.bootstrap.Slf4jLogger; -import org.sonar.batch.cache.WSLoader; -import org.sonar.batch.cache.WSLoader.LoadStrategy; -import org.junit.Rule; -import org.junit.rules.TemporaryFolder; -import static org.mockito.Mockito.when; -import static org.assertj.core.api.Assertions.assertThat; +import org.sonar.batch.bootstrap.UserProperties; import org.sonar.batch.bootstrapper.EnvironmentInformation; +import org.sonar.batch.cache.WSLoader.LoadStrategy; +import org.sonar.home.cache.DirectoryLock; import org.sonar.home.cache.PersistentCache; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.sonar.home.cache.TTLCacheInvalidation; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -public class WSLoaderTestWithServer { +public class WSLoaderWithServerTest { private static final String RESPONSE_STRING = "this is the content"; @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -48,6 +48,7 @@ public class WSLoaderTestWithServer { private PersistentCache cache; private ServerClient client; private WSLoader loader; + private UserProperties userProps; @Before public void setUp() throws Exception { @@ -58,7 +59,8 @@ public class WSLoaderTestWithServer { when(bootstrapProps.property("sonar.host.url")).thenReturn("http://localhost:" + server.getPort()); client = new ServerClient(bootstrapProps, new EnvironmentInformation("Junit", "4")); - cache = new PersistentCache(temp.getRoot().toPath(), new TTLCacheInvalidation(100_000L), new Slf4jLogger(), null); + cache = new PersistentCache(temp.getRoot().toPath(), new TTLCacheInvalidation(100_000L), new Slf4jLogger(), mock(DirectoryLock.class)); + userProps = mock(UserProperties.class); } @After @@ -70,31 +72,31 @@ public class WSLoaderTestWithServer { @Test public void testCacheOnly() { - loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); + loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client, userProps); makeRequests(); - loader = new WSLoader(LoadStrategy.CACHE_ONLY, cache, client); + loader = new WSLoader(LoadStrategy.CACHE_ONLY, cache, client, userProps); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(3); } @Test public void testCacheFirst() { - loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client); + loader = new WSLoader(LoadStrategy.CACHE_FIRST, cache, client, userProps); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(1); } @Test public void testServerFirst() { - loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client); + loader = new WSLoader(LoadStrategy.SERVER_FIRST, cache, client, userProps); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(3); } @Test public void testCacheStrategyDisabled() { - loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client); + loader = new WSLoader(LoadStrategy.SERVER_ONLY, cache, client, userProps); makeRequests(); assertThat(server.getNumberRequests()).isEqualTo(3); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java index f459a341341..8a18f87a51d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/rule/ActiveRulesProviderTest.java @@ -19,22 +19,23 @@ */ package org.sonar.batch.rule; -import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; - import com.google.common.collect.ImmutableList; +import java.util.LinkedList; +import java.util.List; +import org.apache.commons.lang.mutable.MutableBoolean; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.rule.RuleKey; +import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile; -import java.util.LinkedList; -import java.util.List; - -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.verify; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class ActiveRulesProviderTest { @@ -59,9 +60,9 @@ public class ActiveRulesProviderTest { List<LoadedActiveRule> qp2Rules = ImmutableList.of(r2, r3); List<LoadedActiveRule> qp3Rules = ImmutableList.of(r1, r3); - when(loader.load("qp1", null)).thenReturn(qp1Rules); - when(loader.load("qp2", null)).thenReturn(qp2Rules); - when(loader.load("qp3", null)).thenReturn(qp3Rules); + when(loader.load(eq("qp1"), any(MutableBoolean.class))).thenReturn(qp1Rules); + when(loader.load(eq("qp2"), any(MutableBoolean.class))).thenReturn(qp2Rules); + when(loader.load(eq("qp3"), any(MutableBoolean.class))).thenReturn(qp3Rules); ModuleQProfiles profiles = mockProfiles("qp1", "qp2", "qp3"); ActiveRules activeRules = provider.provide(loader, profiles); @@ -70,9 +71,9 @@ public class ActiveRulesProviderTest { assertThat(activeRules.findAll()).extracting("ruleKey").containsOnly( RuleKey.of("rule1", "rule1"), RuleKey.of("rule2", "rule2"), RuleKey.of("rule3", "rule3")); - verify(loader).load("qp1", null); - verify(loader).load("qp2", null); - verify(loader).load("qp3", null); + verify(loader).load(eq("qp1"), any(MutableBoolean.class)); + verify(loader).load(eq("qp2"), any(MutableBoolean.class)); + verify(loader).load(eq("qp3"), any(MutableBoolean.class)); verifyNoMoreInteractions(loader); } |