Skip to content

Commit

Permalink
SLCORE-988 PR review
Browse files Browse the repository at this point in the history
  • Loading branch information
sophio-japharidze-sonarsource committed Oct 24, 2024
1 parent 3082e3e commit 0db9bab
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 47 deletions.
1 change: 1 addition & 0 deletions API_CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* The method returns a boolean value indicating whether the enterprise C# analyzer should be used or not
* The method returns `true` if a binding exists for config scope AND the related connected server has the enterprise C# plugin (`csharpenterprise`) installed
* The method returns `true` if binding exists with a SonarQube version < 10.8 (i.e. SQ versions that do not include repackaged dotnet analyzer) OR SonarCloud
* The method returns `false` in standalone mode or if connected to non-commercial edition of SonarQube with a version >= 10.8

# 10.7.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
import org.sonarsource.sonarlint.core.rules.RulesService;
import org.sonarsource.sonarlint.core.rules.StandaloneRulesConfigurationChanged;
import org.sonarsource.sonarlint.core.serverapi.rules.ServerActiveRule;
import org.sonarsource.sonarlint.core.serverconnection.StoredPlugin;
import org.sonarsource.sonarlint.core.storage.StorageService;
import org.sonarsource.sonarlint.core.sync.AnalyzerConfigurationSynchronized;
import org.sonarsource.sonarlint.core.sync.ConfigurationScopesSynchronizedEvent;
Expand All @@ -138,6 +139,7 @@
@Singleton
public class AnalysisService {
private static final Version SECRET_ANALYSIS_MIN_SQ_VERSION = Version.create("9.9");
public static final Version REPACKAGED_DOTNET_ANALYZER_MIN_SQ_VERSION = Version.create("10.8");

private static final SonarLintLogger LOG = SonarLintLogger.get();

Expand Down Expand Up @@ -644,10 +646,22 @@ public boolean shouldUseEnterpriseCSharpAnalyzer(String configurationScopeId) {
} else {
var connectionId = binding.get().getConnectionId();
var connection = connectionConfigurationRepository.getConnectionById(connectionId);
if (connection == null) {
return false;
var isSonarCloud = connection != null && connection.getEndpointParams().isSonarCloud();
var connectionStorage = storageService.connection(connectionId);
if (isSonarCloud) {
return true;
} else {
return connection.hasEnterpriseCSharpPlugin();
var serverInfo = connectionStorage.serverInfo().read();
if (serverInfo.isEmpty()) {
return false;
} else {
// For SQ versions older than 10.8, enterprise C# analyzer was packaged in all editions.
// For newer versions, we need to check if enterprise plugin is present on the server
var serverVersion = serverInfo.get().getVersion();
var supportsRepackagedDotnetAnalyzer = serverVersion.compareToIgnoreQualifier(REPACKAGED_DOTNET_ANALYZER_MIN_SQ_VERSION) >= 0;
var hasEnterprisePlugin = connectionStorage.plugins().getStoredPlugins().stream().map(StoredPlugin::getKey).anyMatch("csharpenterprise"::equals);
return !supportsRepackagedDotnetAnalyzer || hasEnterprisePlugin;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ public abstract class AbstractConnectionConfiguration {
private final boolean disableNotifications;
private final ConnectionKind kind;
private final String url;
private boolean hasEnterpriseCSharpPlugin = false;

protected AbstractConnectionConfiguration(String connectionId, ConnectionKind kind, boolean disableNotifications, String url) {
Objects.requireNonNull(connectionId, "Connection id is mandatory");
Expand Down Expand Up @@ -76,14 +75,6 @@ public boolean isSameServerUrl(String otherUrl) {
return Objects.equals(myUri, otherUri);
}

public void setHasEnterpriseCSharpPlugin(boolean hasEnterpriseCSharpPlugin) {
this.hasEnterpriseCSharpPlugin = hasEnterpriseCSharpPlugin;
}

public boolean hasEnterpriseCSharpPlugin() {
return hasEnterpriseCSharpPlugin;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import org.sonarsource.sonarlint.core.progress.ProgressNotifier;
import org.sonarsource.sonarlint.core.progress.TaskManager;
import org.sonarsource.sonarlint.core.repository.config.ConfigurationRepository;
import org.sonarsource.sonarlint.core.repository.connection.ConnectionConfigurationRepository;
import org.sonarsource.sonarlint.core.rpc.protocol.SonarLintRpcClient;
import org.sonarsource.sonarlint.core.rpc.protocol.backend.initialize.InitializeParams;
import org.sonarsource.sonarlint.core.rpc.protocol.client.sync.DidSynchronizeConfigurationScopeParams;
Expand Down Expand Up @@ -100,13 +99,12 @@ public class SynchronizationService {
private final ExecutorServiceShutdownWatchable<ScheduledExecutorService> scheduledSynchronizer = new ExecutorServiceShutdownWatchable<>(
Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "SonarLint Local Storage Synchronizer")));
private final Set<String> ignoreBranchEventForScopes = ConcurrentHashMap.newKeySet();
private final ConnectionConfigurationRepository connectionConfigurationRepository;

public SynchronizationService(SonarLintRpcClient client, ConfigurationRepository configurationRepository, LanguageSupportRepository languageSupportRepository,
ServerApiProvider serverApiProvider, StorageService storageService, InitializeParams params, TaintSynchronizationService taintSynchronizationService,
IssueSynchronizationService issueSynchronizationService, HotspotSynchronizationService hotspotSynchronizationService,
SonarProjectBranchesSynchronizationService sonarProjectBranchesSynchronizationService, SonarProjectBranchTrackingService sonarProjectBranchTrackingService,
PluginsRepository pluginsRepository, ApplicationEventPublisher applicationEventPublisher, ConnectionConfigurationRepository connectionConfigurationRepository) {
PluginsRepository pluginsRepository, ApplicationEventPublisher applicationEventPublisher) {
this.client = client;
this.configurationRepository = configurationRepository;
this.languageSupportRepository = languageSupportRepository;
Expand All @@ -123,7 +121,6 @@ public SynchronizationService(SonarLintRpcClient client, ConfigurationRepository
this.sonarProjectBranchTrackingService = sonarProjectBranchTrackingService;
this.pluginsRepository = pluginsRepository;
this.applicationEventPublisher = applicationEventPublisher;
this.connectionConfigurationRepository = connectionConfigurationRepository;
}

@PostConstruct
Expand Down Expand Up @@ -312,7 +309,6 @@ private void synchronizeConnectionAndProjectsIfNeededSync(String connectionId, S
pluginsRepository.unload(connectionId);
applicationEventPublisher.publishEvent(new PluginsSynchronizedEvent(connectionId));
}
updateConnectionDetails(connectionId, summary.canUseEnterpriseDotnetPlugin());
scopesToSync = scopesToSync.stream()
.filter(boundScope -> shouldSynchronizeBinding(new Binding(connectionId, boundScope.getSonarProjectKey()))).collect(toList());
var scopesPerProjectKey = scopesToSync.stream()
Expand Down Expand Up @@ -340,13 +336,6 @@ private void synchronizeConnectionAndProjectsIfNeededSync(String connectionId, S
}
}

private void updateConnectionDetails(String connectionId, boolean hasEnterprisePlugin) {
var connection = connectionConfigurationRepository.getConnectionById(connectionId);
if (connection != null) {
connection.setHasEnterpriseCSharpPlugin(hasEnterprisePlugin);
}
}

private boolean shouldSynchronizeBinding(Binding binding) {
boolean result = bindingSynchronizationTimestampRepository.getLastSynchronizationDate(binding)
.map(lastSync -> lastSync.isBefore(Instant.now().minus(getSyncPeriod(), ChronoUnit.SECONDS)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

import static java.util.stream.Collectors.toSet;
import static org.sonarsource.sonarlint.core.serverconnection.PluginsSynchronizer.CUSTOM_SECRETS_MIN_SQ_VERSION;
import static org.sonarsource.sonarlint.core.serverconnection.PluginsSynchronizer.REPACKAGED_DOTNET_ANALYZER_MIN_SQ_VERSION;

public class LocalStorageSynchronizer {
private static final SonarLintLogger LOG = SonarLintLogger.get();
Expand All @@ -58,9 +57,7 @@ public PluginSynchronizationSummary synchronizeServerInfosAndPlugins(ServerApi s
// downloaded for the first time and also everytime the plug-ins are refreshed (e.g. after IDE restart).
var supportsCustomSecrets = !serverApi.isSonarCloud()
&& version.compareToIgnoreQualifier(CUSTOM_SECRETS_MIN_SQ_VERSION) >= 0;
var supportsRepackagedDotnetAnalyzer = !serverApi.isSonarCloud()
&& version.compareToIgnoreQualifier(REPACKAGED_DOTNET_ANALYZER_MIN_SQ_VERSION) >= 0;
return pluginsSynchronizer.synchronize(serverApi, supportsCustomSecrets, supportsRepackagedDotnetAnalyzer, cancelMonitor);
return pluginsSynchronizer.synchronize(serverApi, supportsCustomSecrets, cancelMonitor);
}

private static AnalyzerSettingsUpdateSummary diffAnalyzerConfiguration(AnalyzerConfiguration original, AnalyzerConfiguration updated) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,12 @@

public class PluginSynchronizationSummary {
private final boolean anyPluginSynchronized;
private final boolean canUseEnterpriseDotnetPlugin;

public PluginSynchronizationSummary(boolean anyPluginSynchronized, boolean enterprisePluginPresent) {
public PluginSynchronizationSummary(boolean anyPluginSynchronized) {
this.anyPluginSynchronized = anyPluginSynchronized;
this.canUseEnterpriseDotnetPlugin = enterprisePluginPresent;
}

public boolean anyPluginSynchronized() {
return anyPluginSynchronized;
}

public boolean canUseEnterpriseDotnetPlugin() {
return canUseEnterpriseDotnetPlugin;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

public class PluginsSynchronizer {
public static final Version CUSTOM_SECRETS_MIN_SQ_VERSION = Version.create("10.4");
public static final Version REPACKAGED_DOTNET_ANALYZER_MIN_SQ_VERSION = Version.create("10.8");
private static final SonarLintLogger LOG = SonarLintLogger.get();

private final Set<String> sonarSourceDisabledPluginKeys;
Expand All @@ -50,8 +49,7 @@ public PluginsSynchronizer(Set<SonarLanguage> enabledLanguages, ConnectionStorag
this.embeddedPluginKeys = embeddedPluginKeys;
}

public PluginSynchronizationSummary synchronize(ServerApi serverApi, boolean supportsCustomSecrets,
boolean supportsRepackagedEnterpriseDotnetAnalyzer, SonarLintCancelMonitor cancelMonitor) {
public PluginSynchronizationSummary synchronize(ServerApi serverApi, boolean supportsCustomSecrets, SonarLintCancelMonitor cancelMonitor) {
if (supportsCustomSecrets) {
var embeddedPluginKeysCopy = new HashSet<>(embeddedPluginKeys);
embeddedPluginKeysCopy.remove(SonarLanguage.SECRETS.getPluginKey());
Expand All @@ -64,17 +62,12 @@ public PluginSynchronizationSummary synchronize(ServerApi serverApi, boolean sup
.filter(p -> shouldDownload(p, storedPluginsByKey))
.collect(Collectors.toList());

var enterpriseDotnetAnalyzerInstalled = serverPlugins.stream().map(ServerPlugin::getKey).anyMatch(key -> key.contains("csharpenterprise"));
// For SQ versions older than 10.8, enterprise C# analyzer was packaged in all editions.
// For newer versions, we need to check if enterprise plugin is present on the server
var usesEnterpriseDotnetAnalyzer = !supportsRepackagedEnterpriseDotnetAnalyzer || enterpriseDotnetAnalyzerInstalled;

if (pluginsToDownload.isEmpty()) {
storage.plugins().storeNoPlugins();
return new PluginSynchronizationSummary(false, usesEnterpriseDotnetAnalyzer);
return new PluginSynchronizationSummary(false);
}
downloadAll(serverApi, pluginsToDownload, cancelMonitor);
return new PluginSynchronizationSummary(true, usesEnterpriseDotnetAnalyzer);
return new PluginSynchronizationSummary(true);
}

private void downloadAll(ServerApi serverApi, List<ServerPlugin> pluginsToDownload, SonarLintCancelMonitor cancelMonitor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void should_not_synchronize_sonar_text_pre_104(@TempDir Path dest) {
"]}");

underTest = new PluginsSynchronizer(Set.of(SonarLanguage.SECRETS), new ConnectionStorage(dest, dest, "connectionId"), Set.of("text"));
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), false, false, new SonarLintCancelMonitor());
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), false, new SonarLintCancelMonitor());

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).exists();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-plugin-1.2.3.4.jar")).doesNotExist();
Expand All @@ -73,7 +73,7 @@ void should_not_synchronize_sonar_text_post_103(@TempDir Path dest) {
mockServer.addStringResponse("/api/plugins/download?plugin=textenterprise", "content-textenterprise");

underTest = new PluginsSynchronizer(Set.of(SonarLanguage.SECRETS), new ConnectionStorage(dest, dest, "connectionId"), Set.of("text"));
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), true, false, new SonarLintCancelMonitor());
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), true, new SonarLintCancelMonitor());

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).exists();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-plugin-2.3.4.5.jar")).exists();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -872,11 +872,14 @@ void it_should_not_use_enterprise_csharp_analyzer_in_standalone() {

@Test
void it_should_not_use_enterprise_csharp_analyzer_when_connected_to_community() {
server = newSonarQubeServer("10.8").start();
backend = newBackend()
.withSonarQubeConnection("connectionId",
server,
storage -> storage.withPlugin(TestPlugin.XML).withProject("projectKey", project -> project.withRuleSet("xml", ruleSet -> ruleSet.withActiveRule("xml:S3421", "BLOCKER"))))
.withBoundConfigScope(CONFIG_SCOPE_ID, "connectionId", "projectKey")
.withExtraEnabledLanguagesInConnectedMode(Language.XML)
.withFullSynchronization()
.build();

var result = backend.getAnalysisService().shouldUseEnterpriseCSharpAnalyzer(new ShouldUseEnterpriseCSharpAnalyzerParams(CONFIG_SCOPE_ID)).join();
Expand Down

0 comments on commit 0db9bab

Please sign in to comment.