Skip to content

Commit

Permalink
SLCORE-668: Download sonar-text on SQ 10.4 as well (#847)
Browse files Browse the repository at this point in the history
It wasn't downloaded on SQ 10.4 DEV because it was still concidered to be embedded when the synchonization was happening.
  • Loading branch information
thahnen authored Jan 29, 2024
1 parent 2e6e3db commit c99c071
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,13 @@ public SynchronizationResult synchronize(ServerApi serverApi, Set<String> projec
serverInfoSynchronizer.synchronize(serverApi);
var version = storage.serverInfo().read().orElseThrow().getVersion();

var anyPluginUpdated = pluginsSynchronizer.synchronize(serverApi, progressMonitor);
// INFO: In order to download `sonar-text` alongside `sonar-text-enterprise` on SQ 10.4+ we have to change the
// plug-in synchronizer to work correctly the moment the connection is established and the plug-ins are
// downloaded for the first time and also everytime the plug-ins are refreshed (e.g. after IDE restart).
var supportsCustomSecrets = !serverApi.isSonarCloud()
&& version.compareToIgnoreQualifier(ServerConnection.CUSTOM_SECRETS_MIN_SQ_VERSION) >= 0;
var anyPluginUpdated = pluginsSynchronizer.synchronize(serverApi, progressMonitor, supportsCustomSecrets);

projectKeys.stream()
.collect(Collectors.toMap(Function.identity(), projectKey -> synchronizeAnalyzerConfig(serverApi, projectKey, progressMonitor)))
.forEach((projectKey, analyzerConfig) -> storage.project(projectKey).analyzerConfiguration().store(analyzerConfig));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -37,16 +38,22 @@ public class PluginsSynchronizer {

private final Set<String> sonarSourceDisabledPluginKeys;
private final ConnectionStorage storage;
private final Set<String> embeddedPluginKeys;
private final PluginsMinVersions pluginsMinVersions = new PluginsMinVersions();
private Set<String> embeddedPluginKeys;

public PluginsSynchronizer(Set<Language> enabledLanguages, ConnectionStorage storage, Set<String> embeddedPluginKeys) {
this.sonarSourceDisabledPluginKeys = getSonarSourceDisabledPluginKeys(enabledLanguages);
this.storage = storage;
this.embeddedPluginKeys = embeddedPluginKeys;
}

public boolean synchronize(ServerApi serverApi, ProgressMonitor progressMonitor) {
public boolean synchronize(ServerApi serverApi, ProgressMonitor progressMonitor, boolean supportsCustomSecrets) {
if (supportsCustomSecrets) {
var embeddedPluginKeysCopy = new HashSet<>(embeddedPluginKeys);
embeddedPluginKeysCopy.remove(Language.SECRETS.getPluginKey());
embeddedPluginKeys = embeddedPluginKeysCopy;
}

var storedPluginsByKey = storage.plugins().getStoredPluginsByKey();
var serverPlugins = serverApi.plugins().getInstalled();
var pluginsToDownload = serverPlugins.stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
public class ServerConnection {
private static final SonarLintLogger LOG = SonarLintLogger.get();
private static final Version SECRET_ANALYSIS_MIN_SQ_VERSION = Version.create("9.9");
private static final Version CUSTOM_SECRETS_MIN_SQ_VERSION = Version.create("10.4");
public static final Version CUSTOM_SECRETS_MIN_SQ_VERSION = Version.create("10.4");

private static final Version CLEAN_CODE_TAXONOMY_MIN_SQ_VERSION = Version.create("10.2");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void should_synchronize_plugins(@TempDir Path tmp) throws Exception {
mockServer.addStringResponse("/api/plugins/download?plugin=javascript", "content-js");

underTest = new PluginsSynchronizer(Set.of(Language.JAVA, Language.JS), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

var references = ProtobufFileUtil.readFile(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb"), PluginReferences.parser());
assertThat(references.getPluginsByKeyMap().values()).extracting("key", "hash", "filename")
Expand All @@ -76,10 +76,10 @@ void should_not_synchronize_an_up_to_date_plugin(@TempDir Path tmp) throws Excep
"]}");
mockServer.addStringResponse("/api/plugins/download?plugin=java", "content-java");
underTest = new PluginsSynchronizer(Set.of(Language.JAVA), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);
mockServer.removeResponse("/api/plugins/download?plugin=java");

var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(anyPluginUpdated).isFalse();
}
Expand All @@ -93,13 +93,13 @@ void should_synchronize_a_plugin_when_hash_is_different(@TempDir Path tmp) throw
"]}");
mockServer.addStringResponse("/api/plugins/download?plugin=java", "content-java");
underTest = new PluginsSynchronizer(Set.of(Language.JAVA), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);
mockServer.addStringResponse("/api/plugins/installed", "{\"plugins\": [" +
"{\"key\": \"java\", \"hash\": \"79dba9cab72d8d31767f47c03d169598\", \"filename\": \"sonar-java-plugin-5.14.0.18485.jar\", \"sonarLintSupported\": true}" +
"]}");
mockServer.addStringResponse("/api/plugins/download?plugin=java", "content-java2");

var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

var references = ProtobufFileUtil.readFile(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb"), PluginReferences.parser());
assertThat(references.getPluginsByKeyMap().values()).extracting("key", "hash", "filename")
Expand All @@ -116,7 +116,7 @@ void should_not_synchronize_plugins_that_do_not_support_sonarlint(@TempDir Path
"]}");

underTest = new PluginsSynchronizer(Set.of(Language.JAVA), new ConnectionStorage(dest, dest, "connectionId"), Set.of());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).doesNotExist();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-java-plugin-5.13.1.18282.jar")).doesNotExist();
Expand All @@ -130,7 +130,7 @@ void should_not_synchronize_plugins_with_unsupported_version(@TempDir Path dest)
"]}");

underTest = new PluginsSynchronizer(Set.of(Language.JAVA), new ConnectionStorage(dest, dest, "connectionId"), Set.of());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).doesNotExist();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-java-plugin-5.12.0.jar")).doesNotExist();
Expand All @@ -144,7 +144,7 @@ void should_not_synchronize_embedded_plugins(@TempDir Path dest) {
"]}");

underTest = new PluginsSynchronizer(Set.of(Language.JAVA), new ConnectionStorage(dest, dest, "connectionId"), Set.of("java"));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).doesNotExist();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-java-plugin-5.13.1.18282.jar")).doesNotExist();
Expand All @@ -159,7 +159,7 @@ void should_not_synchronize_plugins_for_not_enabled_languages(@TempDir Path tmp)
"]}");

underTest = new PluginsSynchronizer(Set.of(Language.JS), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).doesNotExist();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-java-plugin-5.13.1.18282.jar")).doesNotExist();
Expand All @@ -175,7 +175,7 @@ void should_synchronize_unknown_plugins_for_custom_rules(@TempDir Path tmp) {
mockServer.addStringResponse("/api/plugins/download?plugin=java-custom", "content-java-custom");

underTest = new PluginsSynchronizer(Set.of(Language.JS), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

var references = ProtobufFileUtil.readFile(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb"), PluginReferences.parser());
assertThat(references.getPluginsByKeyMap().values()).extracting("key", "hash", "filename")
Expand All @@ -195,7 +195,7 @@ void should_synchronize_the_old_typescript_plugin_if_language_enabled(@TempDir P
mockServer.addStringResponse("/api/plugins/download?plugin=typescript", "content-ts");

underTest = new PluginsSynchronizer(Set.of(Language.TS), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

var references = ProtobufFileUtil.readFile(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb"), PluginReferences.parser());
assertThat(references.getPluginsByKeyMap().values()).extracting("key", "hash", "filename")
Expand All @@ -214,10 +214,51 @@ void should_not_synchronize_the_old_typescript_plugin_if_language_not_enabled(@T
"]}");

underTest = new PluginsSynchronizer(Set.of(Language.JAVA), new ConnectionStorage(dest, tmp, "connectionId"), emptySet());
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/636f6e6e656374696f6e4964/plugin_references.pb")).doesNotExist();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-typescript-plugin-1.9.0.3766.jar")).doesNotExist();
assertThat(anyPluginUpdated).isFalse();
}

/**
* Emulating SonarQube 10.3 where custom secrets are not enabled and `sonar-text` is embedded and
* `sonar-text-enterprise` not downloaded because it is not supporting SonarLint yet!
*/
@Test
void should_not_synchronize_sonar_text_pre_104(@TempDir Path dest) {
mockServer.addStringResponse("/api/plugins/installed", "{\"plugins\": [" +
"{\"key\": \"text\", \"hash\": \"de5308f43260d357acc97712ce4c5475\", \"filename\": \"sonar-text-plugin-1.2.3.4.jar\", \"sonarLintSupported\": true}," +
"{\"key\": \"textenterprise\", \"hash\": \"de5308f43260d357acc97712ce4c5475\", \"filename\": \"sonar-text-enterprise-plugin-5.6.7.8.jar\", \"sonarLintSupported\": false}" +
"]}");

underTest = new PluginsSynchronizer(Set.of(Language.SECRETS), new ConnectionStorage(dest, dest, "connectionId"), Set.of("text"));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), false);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).doesNotExist();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-plugin-1.2.3.4.jar")).doesNotExist();
assertThat(anyPluginUpdated).isFalse();
}

/**
* Emulating SonarQube 10.4 where custom secrets are enabled and `sonar-text` is embedded but will be downloaded
* alongside `sonar-text-enterprise` because it is now supporting SonarLint!
*/
@Test
void should_not_synchronize_sonar_text_post_103(@TempDir Path dest) {
mockServer.addStringResponse("/api/plugins/installed", "{\"plugins\": [" +
"{\"key\": \"text\", \"hash\": \"de5308f43260d357acc97712ce4c5475\", \"filename\": \"sonar-text-plugin-1.2.3.4.jar\", \"sonarLintSupported\": true}," +
"{\"key\": \"textenterprise\", \"hash\": \"de5308f43260d357acc97712ce4c5475\", \"filename\": \"sonar-text-enterprise-plugin-5.6.7.8.jar\", \"sonarLintSupported\": true}" +
"]}");
mockServer.addStringResponse("/api/plugins/download?plugin=text", "content-text");
mockServer.addStringResponse("/api/plugins/download?plugin=textenterprise", "content-textenterprise");

underTest = new PluginsSynchronizer(Set.of(Language.SECRETS), new ConnectionStorage(dest, dest, "connectionId"), Set.of("text"));
var anyPluginUpdated = underTest.synchronize(new ServerApi(mockServer.serverApiHelper()), new ProgressMonitor(null), true);

assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/plugin_references.pb")).exists();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-plugin-1.2.3.4.jar")).exists();
assertThat(dest.resolve("636f6e6e656374696f6e4964/plugins/sonar-text-enterprise-plugin-5.6.7.8.jar")).exists();
assertThat(anyPluginUpdated).isTrue();
}
}

0 comments on commit c99c071

Please sign in to comment.