From 1220331cf405fb916a005284120b0ed02ea67ac2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?L=C3=A9o=20Geoffroy?= <99647462+leo-geoffroy-sonarsource@users.noreply.github.com> Date: Fri, 22 Jul 2022 17:40:51 +0200 Subject: [PATCH] SONAR-17081 - Minimal compatibility version should be compared with runtime API version --- .../sonar/server/plugins/PluginJarLoader.java | 17 ++++++----- .../server/plugins/PluginJarLoaderTest.java | 14 ++++----- .../core/platform/PluginClassLoader.java | 4 +-- .../org/sonar/core/platform/PluginInfo.java | 30 +++++++++---------- .../core/platform/PluginClassLoaderTest.java | 4 +-- .../sonar/core/platform/PluginInfoTest.java | 8 ++--- .../sonar/api/internal/SonarRuntimeImpl.java | 4 +-- 7 files changed, 41 insertions(+), 40 deletions(-) diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/PluginJarLoader.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/PluginJarLoader.java index d04845aaf78..19d14265082 100644 --- a/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/PluginJarLoader.java +++ b/server/sonar-webserver-api/src/main/java/org/sonar/server/plugins/PluginJarLoader.java @@ -34,11 +34,11 @@ import java.util.function.Function; import java.util.stream.Collectors; import javax.inject.Inject; import org.apache.commons.io.FileUtils; +import org.sonar.api.SonarRuntime; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.core.platform.PluginInfo; -import org.sonar.core.platform.SonarQubeVersion; import org.sonar.server.platform.ServerFileSystem; import static java.lang.String.format; @@ -60,17 +60,17 @@ public class PluginJarLoader { private static final String LOAD_ERROR_GENERIC_MESSAGE = "Startup failed: Plugins can't be loaded. See web logs for more information"; private final ServerFileSystem fs; - private final SonarQubeVersion sonarQubeVersion; + private final SonarRuntime sonarRuntime; private final Set blacklistedPluginKeys; @Inject - public PluginJarLoader(ServerFileSystem fs, SonarQubeVersion sonarQubeVersion) { - this(fs, sonarQubeVersion, DEFAULT_BLACKLISTED_PLUGINS); + public PluginJarLoader(ServerFileSystem fs, SonarRuntime sonarRuntime) { + this(fs, sonarRuntime, DEFAULT_BLACKLISTED_PLUGINS); } - PluginJarLoader(ServerFileSystem fs, SonarQubeVersion sonarQubeVersion, Set blacklistedPluginKeys) { + PluginJarLoader(ServerFileSystem fs, SonarRuntime sonarRuntime, Set blacklistedPluginKeys) { this.fs = fs; - this.sonarQubeVersion = sonarQubeVersion; + this.sonarRuntime = sonarRuntime; this.blacklistedPluginKeys = blacklistedPluginKeys; } @@ -211,8 +211,9 @@ public class PluginJarLoader { return false; } - if (!info.isCompatibleWith(sonarQubeVersion.get().toString())) { - throw MessageException.of(format("Plugin %s [%s] requires at least SonarQube %s", info.getName(), info.getKey(), info.getMinimalSqVersion())); + if (!info.isCompatibleWith(sonarRuntime.getApiVersion().toString())) { + throw MessageException.of(format("Plugin %s [%s] requires at least Sonar Plugin API version %s (current: %s)", + info.getName(), info.getKey(), info.getMinimalSonarPluginApiVersion(), sonarRuntime.getApiVersion())); } return true; } diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/plugins/PluginJarLoaderTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/plugins/PluginJarLoaderTest.java index c8be970cc3d..36ce28aa56f 100644 --- a/server/sonar-webserver-api/src/test/java/org/sonar/server/plugins/PluginJarLoaderTest.java +++ b/server/sonar-webserver-api/src/test/java/org/sonar/server/plugins/PluginJarLoaderTest.java @@ -35,10 +35,10 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.api.SonarRuntime; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.log.LogTester; import org.sonar.core.platform.PluginInfo; -import org.sonar.core.platform.SonarQubeVersion; import org.sonar.server.platform.ServerFileSystem; import org.sonar.updatecenter.common.PluginManifest; @@ -56,12 +56,12 @@ public class PluginJarLoaderTest { private final ServerFileSystem fs = mock(ServerFileSystem.class); private final Set blacklisted = new HashSet<>(); - private final SonarQubeVersion sonarQubeVersion = mock(SonarQubeVersion.class); - private final PluginJarLoader underTest = new PluginJarLoader(fs, sonarQubeVersion, blacklisted); + private final SonarRuntime sonarRuntime = mock(SonarRuntime.class); + private final PluginJarLoader underTest = new PluginJarLoader(fs, sonarRuntime, blacklisted); @Before public void setUp() throws IOException { - when(sonarQubeVersion.get()).thenReturn(org.sonar.api.utils.Version.parse("5.2")); + when(sonarRuntime.getApiVersion()).thenReturn(org.sonar.api.utils.Version.parse("5.2")); when(fs.getDeployedPluginsDir()).thenReturn(temp.newFolder("deployed")); when(fs.getDownloadedPluginsDir()).thenReturn(temp.newFolder("downloaded")); when(fs.getHomeDir()).thenReturn(temp.newFolder("home")); @@ -285,12 +285,12 @@ public class PluginJarLoaderTest { } @Test - public void fail_if_plugin_does_not_support_sq_version() throws Exception { - when(sonarQubeVersion.get()).thenReturn(org.sonar.api.utils.Version.parse("1.0")); + public void fail_if_plugin_does_not_support_plugin_api_version() throws Exception { + when(sonarRuntime.getApiVersion()).thenReturn(org.sonar.api.utils.Version.parse("1.0")); copyTestPluginTo("test-base-plugin", fs.getInstalledExternalPluginsDir()); assertThatThrownBy(() -> underTest.loadPlugins()) - .hasMessage("Plugin Base Plugin [testbase] requires at least SonarQube 4.5.4"); + .hasMessage("Plugin Base Plugin [testbase] requires at least Sonar Plugin API version 4.5.4 (current: 1.0)"); } private static File copyTestPluginTo(String testPluginName, File toDir) throws IOException { diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoader.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoader.java index 75f6f83c074..624218bec58 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoader.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginClassLoader.java @@ -98,8 +98,8 @@ public class PluginClassLoader { Loggers.get(getClass()).warn("Plugin {} [{}] uses a child first classloader which is deprecated", info.getName(), info.getKey()); } def.setSelfFirstStrategy(info.isUseChildFirstClassLoader()); - Version minSqVersion = info.getMinimalSqVersion(); - boolean compatibilityMode = minSqVersion != null && minSqVersion.compareToIgnoreQualifier(COMPATIBILITY_MODE_MAX_VERSION) < 0; + Version minSonarPluginApiVersion = info.getMinimalSonarPluginApiVersion(); + boolean compatibilityMode = minSonarPluginApiVersion != null && minSonarPluginApiVersion.compareToIgnoreQualifier(COMPATIBILITY_MODE_MAX_VERSION) < 0; if (compatibilityMode) { Loggers.get(getClass()).warn("API compatibility mode is no longer supported. In case of error, plugin {} [{}] should package its dependencies.", info.getName(), info.getKey()); diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java index 6e8dd8463b4..729b22d9e52 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfo.java @@ -64,7 +64,7 @@ public class PluginInfo implements Comparable { private String displayVersion; @CheckForNull - private Version minimalSqVersion; + private Version minimalSonarPluginApiVersion; @CheckForNull private String description; @@ -145,8 +145,8 @@ public class PluginInfo implements Comparable { } @CheckForNull - public Version getMinimalSqVersion() { - return minimalSqVersion; + public Version getMinimalSonarPluginApiVersion() { + return minimalSonarPluginApiVersion; } @CheckForNull @@ -220,8 +220,8 @@ public class PluginInfo implements Comparable { return this; } - public PluginInfo setMinimalSqVersion(@Nullable Version v) { - this.minimalSqVersion = v; + public PluginInfo setMinimalSonarPluginApiVersion(@Nullable Version v) { + this.minimalSonarPluginApiVersion = v; return this; } @@ -300,20 +300,20 @@ public class PluginInfo implements Comparable { } /** - * Find out if this plugin is compatible with a given version of SonarQube. - * The version of SQ must be greater than or equal to the minimal version + * Find out if this plugin is compatible with a given version of Sonar Plugin API. + * The version of plugin api embedded in SQ must be greater than or equal to the minimal version * needed by the plugin. */ - public boolean isCompatibleWith(String runtimeVersion) { - if (null == this.minimalSqVersion) { + public boolean isCompatibleWith(String runtimePluginApiVersion) { + if (null == this.minimalSonarPluginApiVersion) { // no constraint defined on the plugin return true; } - Version effectiveMin = Version.create(minimalSqVersion.getName()).removeQualifier(); - Version effectiveVersion = Version.create(runtimeVersion).removeQualifier(); + Version effectiveMin = Version.create(minimalSonarPluginApiVersion.getName()).removeQualifier(); + Version effectiveVersion = Version.create(runtimePluginApiVersion).removeQualifier(); - if (runtimeVersion.endsWith("-SNAPSHOT")) { + if (runtimePluginApiVersion.endsWith("-SNAPSHOT")) { // check only the major and minor versions (two first fields) effectiveMin = Version.create(effectiveMin.getMajor() + "." + effectiveMin.getMinor()); } @@ -389,9 +389,9 @@ public class PluginInfo implements Comparable { setOrganizationName(manifest.getOrganization()); setOrganizationUrl(manifest.getOrganizationUrl()); setDisplayVersion(manifest.getDisplayVersion()); - String minSqVersion = manifest.getSonarVersion(); - if (minSqVersion != null) { - setMinimalSqVersion(Version.create(minSqVersion)); + String minSonarPluginApiVersion = manifest.getSonarVersion(); + if (minSonarPluginApiVersion != null) { + setMinimalSonarPluginApiVersion(Version.create(minSonarPluginApiVersion)); } setHomepageUrl(manifest.getHomepage()); setIssueTrackerUrl(manifest.getIssueTrackerUrl()); diff --git a/sonar-core/src/test/java/org/sonar/core/platform/PluginClassLoaderTest.java b/sonar-core/src/test/java/org/sonar/core/platform/PluginClassLoaderTest.java index 53806373452..231e022007e 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/PluginClassLoaderTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/PluginClassLoaderTest.java @@ -54,7 +54,7 @@ public class PluginClassLoaderTest { PluginInfo plugin = new PluginInfo("foo") .setJarFile(jarFile) .setMainClass("org.foo.FooPlugin") - .setMinimalSqVersion(Version.create("5.2")); + .setMinimalSonarPluginApiVersion(Version.create("5.2")); ExplodedPlugin explodedPlugin = createExplodedPlugin(plugin); Collection defs = underTest.defineClassloaders( @@ -141,7 +141,7 @@ public class PluginClassLoaderTest { PluginInfo info = new PluginInfo("foo") .setJarFile(jarFile) .setMainClass("org.foo.FooPlugin") - .setMinimalSqVersion(Version.create("4.5.2")); + .setMinimalSonarPluginApiVersion(Version.create("4.5.2")); Collection defs = underTest.defineClassloaders( ImmutableMap.of("foo", createExplodedPlugin(info))); diff --git a/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java b/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java index 89200041113..9a7ecd05e58 100644 --- a/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/platform/PluginInfoTest.java @@ -187,7 +187,7 @@ public class PluginInfoTest { assertThat(pluginInfo.getLicense()).isNull(); assertThat(pluginInfo.getOrganizationName()).isNull(); assertThat(pluginInfo.getOrganizationUrl()).isNull(); - assertThat(pluginInfo.getMinimalSqVersion()).isNull(); + assertThat(pluginInfo.getMinimalSonarPluginApiVersion()).isNull(); assertThat(pluginInfo.getRequiredPlugins()).isEmpty(); assertThat(pluginInfo.isSonarLintSupported()).isFalse(); } @@ -222,7 +222,7 @@ public class PluginInfoTest { assertThat(pluginInfo.getLicense()).isEqualTo("LGPL"); assertThat(pluginInfo.getOrganizationName()).isEqualTo("SonarSource"); assertThat(pluginInfo.getOrganizationUrl()).isEqualTo("http://sonarsource.com"); - assertThat(pluginInfo.getMinimalSqVersion().getName()).isEqualTo("4.5.1"); + assertThat(pluginInfo.getMinimalSonarPluginApiVersion().getName()).isEqualTo("4.5.1"); assertThat(pluginInfo.getRequiredPlugins()).extracting("key").containsOnly("java", "pmd"); assertThat(pluginInfo.isSonarLintSupported()).isTrue(); } @@ -272,7 +272,7 @@ public class PluginInfoTest { assertThat(checkstyleInfo.getName()).isEqualTo("Checkstyle"); assertThat(checkstyleInfo.getDocumentationPath()).isNull(); - assertThat(checkstyleInfo.getMinimalSqVersion()).isEqualTo(Version.create("2.8")); + assertThat(checkstyleInfo.getMinimalSonarPluginApiVersion()).isEqualTo(Version.create("2.8")); } @Test @@ -319,7 +319,7 @@ public class PluginInfoTest { PluginInfo withMinSqVersion(@Nullable String version) { PluginInfo pluginInfo = new PluginInfo("foo"); if (version != null) { - pluginInfo.setMinimalSqVersion(Version.create(version)); + pluginInfo.setMinimalSonarPluginApiVersion(Version.create(version)); } return pluginInfo; } diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java index 051b567bc54..7ace1b55449 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java @@ -80,8 +80,8 @@ public class SonarRuntimeImpl implements SonarRuntime { /** * Create an instance for SonarQube runtime environment. */ - public static SonarRuntime forSonarQube(Version version, SonarQubeSide side, SonarEdition edition) { - return new SonarRuntimeImpl(version, SonarProduct.SONARQUBE, side, edition); + public static SonarRuntime forSonarQube(Version apiVersion, SonarQubeSide side, SonarEdition edition) { + return new SonarRuntimeImpl(apiVersion, SonarProduct.SONARQUBE, side, edition); } /** -- 2.39.5