diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2019-04-30 10:52:55 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-05-06 11:01:03 +0200 |
commit | a517a4c1b6afe3c3c202801249dcbea41cfdec4c (patch) | |
tree | b3ffb242da45497fb6f3583123f1f7b58d7eb46c | |
parent | 140aa8271a5af00a84154698b18dc254d5f7bae9 (diff) | |
download | sonarqube-a517a4c1b6afe3c3c202801249dcbea41cfdec4c.tar.gz sonarqube-a517a4c1b6afe3c3c202801249dcbea41cfdec4c.zip |
SONAR-11969 Make Edition available for analyzers in the Scanner API
22 files changed, 210 insertions, 82 deletions
diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java index aac7bbc2ef6..892081dc202 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java @@ -20,6 +20,7 @@ package org.sonar.xoo; import java.util.List; +import org.sonar.api.SonarEdition; import org.junit.Test; import org.sonar.api.Plugin; import org.sonar.api.SonarQubeSide; @@ -30,7 +31,6 @@ import org.sonar.api.utils.Version; import org.sonar.xoo.global.GlobalProjectSensor; import org.sonar.xoo.rule.OneExternalIssuePerLineSensor; import org.sonar.xoo.rule.XooBuiltInQualityProfilesDefinition; -import org.sonar.xoo.scm.XooBlameCommand; import org.sonar.xoo.scm.XooIgnoreCommand; import static org.assertj.core.api.Assertions.assertThat; @@ -49,7 +49,7 @@ public class XooPluginTest { @Test public void provide_extensions_for_6_6() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.6"), SonarQubeSide.SCANNER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.6"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) @@ -59,7 +59,7 @@ public class XooPluginTest { @Test public void provide_extensions_for_7_2() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.2"), SonarQubeSide.SCANNER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.2"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) @@ -69,7 +69,7 @@ public class XooPluginTest { @Test public void provide_extensions_for_7_3() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.3"), SonarQubeSide.SCANNER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.3"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) @@ -79,7 +79,7 @@ public class XooPluginTest { @Test public void provide_extensions_for_7_6() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.6"), SonarQubeSide.SCANNER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("7.6"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build(); new XooPlugin().define(context); assertThat(getExtensions(context)) diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java index 87c1ec21388..ab8a6ddafea 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java @@ -20,6 +20,7 @@ package org.sonar.xoo.rule; import java.io.IOException; +import org.sonar.api.SonarEdition; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -115,7 +116,7 @@ public class OneIssuePerLineSensorTest { SensorContextTester context = SensorContextTester.create(temp.newFolder()); context.fileSystem().add(inputFile); context.settings().setProperty(OneIssuePerLineSensor.EFFORT_TO_FIX_PROPERTY, "1.2"); - context.setRuntime(SonarRuntimeImpl.forSonarQube(Version.parse("5.4"), SonarQubeSide.SCANNER)); + context.setRuntime(SonarRuntimeImpl.forSonarQube(Version.parse("5.4"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY)); sensor.execute(context); diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java index 5e5a10bea79..9ae65aed3a2 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java @@ -19,6 +19,7 @@ */ package org.sonar.xoo.rule; +import org.sonar.api.SonarEdition; import org.junit.Before; import org.junit.Test; import org.sonar.api.SonarQubeSide; @@ -34,7 +35,7 @@ public class XooRulesDefinitionTest { @Before public void setUp() { - XooRulesDefinition def = new XooRulesDefinition(SonarRuntimeImpl.forSonarQube(Version.create(7, 3), SonarQubeSide.SCANNER)); + XooRulesDefinition def = new XooRulesDefinition(SonarRuntimeImpl.forSonarQube(Version.create(7, 3), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY)); context = new RulesDefinition.Context(); def.define(context); } @@ -54,7 +55,7 @@ public class XooRulesDefinitionTest { assertThat(rule.debtRemediationFunction().baseEffort()).isNull(); assertThat(rule.gapDescription()).isNotEmpty(); } - + @Test public void define_xoo_hotspot_rule() { RulesDefinition.Repository repo = context.repository("xoo"); diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index cc7445e259b..313ac49cdce 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -23,10 +23,11 @@ import com.google.common.annotations.VisibleForTesting; import java.time.Clock; import java.util.List; import javax.annotation.CheckForNull; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeVersion; import org.sonar.api.config.EmailSettings; -import org.sonar.api.internal.ApiVersion; +import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.profiles.AnnotationProfileParser; import org.sonar.api.profiles.XMLProfileParser; @@ -265,13 +266,14 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { } private static void populateLevel1(ComponentContainer container, Props props, ComputeEngineStatus computeEngineStatus) { - Version apiVersion = ApiVersion.load(System2.INSTANCE); + Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE); + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); container.add( props.rawProperties(), ThreadLocalSettings.class, new ConfigurationProvider(), new SonarQubeVersion(apiVersion), - SonarRuntimeImpl.forSonarQube(ApiVersion.load(System2.INSTANCE), SonarQubeSide.COMPUTE_ENGINE), + SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.COMPUTE_ENGINE, edition), CeProcessLogging.class, UuidFactoryImpl.INSTANCE, NetworkUtilsImpl.INSTANCE, diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/platform/StartupMetadataProviderTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/platform/StartupMetadataProviderTest.java index e761789a5ca..deaca33baf2 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/platform/StartupMetadataProviderTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/platform/StartupMetadataProviderTest.java @@ -19,6 +19,7 @@ */ package org.sonar.server.platform; +import org.sonar.api.SonarEdition; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -54,7 +55,7 @@ public class StartupMetadataProviderTest { @Test public void generate_SERVER_STARTIME_but_do_not_persist_it_if_server_is_startup_leader() { when(system.now()).thenReturn(A_DATE); - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.SERVER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.SERVER, SonarEdition.COMMUNITY); when(webServer.isStartupLeader()).thenReturn(true); StartupMetadata metadata = underTest.provide(system, runtime, webServer, dbTester.getDbClient()); @@ -69,7 +70,7 @@ public class StartupMetadataProviderTest { @Test public void load_from_database_if_server_is_startup_follower() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.SERVER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.SERVER, SonarEdition.COMMUNITY); when(webServer.isStartupLeader()).thenReturn(false); testLoadingFromDatabase(runtime, false); @@ -77,21 +78,21 @@ public class StartupMetadataProviderTest { @Test public void load_from_database_if_compute_engine_of_startup_leader_server() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.COMPUTE_ENGINE); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.COMPUTE_ENGINE, SonarEdition.COMMUNITY); testLoadingFromDatabase(runtime, true); } @Test public void load_from_database_if_compute_engine_of_startup_follower_server() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.COMPUTE_ENGINE); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.COMPUTE_ENGINE, SonarEdition.COMMUNITY); testLoadingFromDatabase(runtime, false); } @Test public void fail_to_load_from_database_if_properties_are_not_persisted() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.COMPUTE_ENGINE); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.create(6, 1), SonarQubeSide.COMPUTE_ENGINE, SonarEdition.COMMUNITY); when(webServer.isStartupLeader()).thenReturn(false); expectedException.expect(IllegalStateException.class); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/util/OkHttpClientProviderTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/util/OkHttpClientProviderTest.java index 32ed25b0663..b5c880269bb 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/util/OkHttpClientProviderTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/util/OkHttpClientProviderTest.java @@ -28,6 +28,7 @@ import okhttp3.Response; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; +import org.sonar.api.SonarEdition; import org.junit.Rule; import org.junit.Test; import org.sonar.api.SonarQubeSide; @@ -41,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat; public class OkHttpClientProviderTest { private MapSettings settings = new MapSettings(); - private SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.2"), SonarQubeSide.SERVER); + private SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.2"), SonarQubeSide.SERVER, SonarEdition.COMMUNITY); private final OkHttpClientProvider underTest = new OkHttpClientProvider(); @Rule diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java index 0368eac7575..ee8b5cf1e03 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/webhook/WebhookCallerImplTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import org.junit.rules.DisableOnDebug; import org.junit.rules.TestRule; import org.junit.rules.Timeout; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; import org.sonar.api.config.internal.MapSettings; @@ -233,7 +234,7 @@ public class WebhookCallerImplTest { } private WebhookCaller newSender() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.2"), SonarQubeSide.SERVER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.2"), SonarQubeSide.SERVER, SonarEdition.COMMUNITY); return new WebhookCallerImpl(system, new OkHttpClientProvider().provide(new MapSettings().asConfig(), runtime)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java index b15e0d6a2ff..a706b694741 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel1.java @@ -22,9 +22,10 @@ package org.sonar.server.platform.platformlevel; import java.time.Clock; import java.util.Properties; import javax.annotation.Nullable; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeVersion; -import org.sonar.api.internal.ApiVersion; +import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.utils.System2; import org.sonar.api.utils.Version; @@ -82,10 +83,12 @@ public class PlatformLevel1 extends PlatformLevel { public void configureLevel() { add(platform, properties); addExtraRootComponents(); - Version apiVersion = ApiVersion.load(System2.INSTANCE); + Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE); + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + add( new SonarQubeVersion(apiVersion), - SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SERVER), + SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SERVER, edition), ThreadLocalSettings.class, new ConfigurationProvider(), LogServerVersion.class, diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/serverid/ServerIdManagerTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/serverid/ServerIdManagerTest.java index 1947b81d17f..0875ad0fcb2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/serverid/ServerIdManagerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/serverid/ServerIdManagerTest.java @@ -22,6 +22,7 @@ package org.sonar.server.platform.serverid; import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; +import org.sonar.api.SonarEdition; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -355,7 +356,8 @@ public class ServerIdManagerTest { } private void test(SonarQubeSide side) { - underTest = new ServerIdManager(serverIdChecksum, serverIdFactory, dbClient, SonarRuntimeImpl.forSonarQube(Version.create(6, 7), side), webServer); + underTest = new ServerIdManager(serverIdChecksum, serverIdFactory, dbClient, SonarRuntimeImpl + .forSonarQube(Version.create(6, 7), side, SonarEdition.COMMUNITY), webServer); underTest.start(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceFilterTest.java b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceFilterTest.java index 42e2136f6e0..1e58673735d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceFilterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ws/WebServiceFilterTest.java @@ -25,6 +25,7 @@ import javax.servlet.FilterChain; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.sonar.api.SonarEdition; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -58,7 +59,7 @@ public class WebServiceFilterTest { private HttpServletResponse response = mock(HttpServletResponse.class); private FilterChain chain = mock(FilterChain.class); private ServletOutputStream responseOutput = mock(ServletOutputStream.class); - private SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse(RUNTIME_VERSION), SonarQubeSide.SERVER); + private SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse(RUNTIME_VERSION), SonarQubeSide.SERVER, SonarEdition.COMMUNITY); private WebServiceFilter underTest; @Before diff --git a/sonar-core/src/main/java/org/sonar/core/platform/EditionProvider.java b/sonar-core/src/main/java/org/sonar/core/platform/EditionProvider.java index c0c084034af..bccd951b639 100644 --- a/sonar-core/src/main/java/org/sonar/core/platform/EditionProvider.java +++ b/sonar-core/src/main/java/org/sonar/core/platform/EditionProvider.java @@ -21,10 +21,12 @@ package org.sonar.core.platform; import java.util.Optional; import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.scanner.ScannerSide; import org.sonar.api.server.ServerSide; @ServerSide @ComputeEngineSide +@ScannerSide public interface EditionProvider { enum Edition { COMMUNITY("Community"), diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarEdition.java index 5b68a5d7aa4..7cfa5b45ca7 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/ApiVersion.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarEdition.java @@ -17,35 +17,22 @@ * 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.internal; +package org.sonar.api; -import com.google.common.io.Resources; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.Version; +public enum SonarEdition { + COMMUNITY("Community"), + DEVELOPER("Developer"), + ENTERPRISE("Enterprise"), + DATACENTER("Data Center"), + SONARCLOUD("SonarCloud"); -/** - * For internal use - * - * @since 6.0 - */ -public class ApiVersion { - - private static final String FILE_PATH = "/sonar-api-version.txt"; + private final String label; - private ApiVersion() { - // only static methods + SonarEdition(String label) { + this.label = label; } - public static Version load(System2 system) { - try { - URL url = system.getResource(FILE_PATH); - String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); - return Version.parse(versionInFile); - } catch (IOException e) { - throw new IllegalStateException("Can not load " + FILE_PATH + " from classpath", e); - } + public String getLabel() { + return label; } } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java b/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java index 0eecfb6977e..2579288a396 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/SonarRuntime.java @@ -20,11 +20,10 @@ package org.sonar.api; import javax.annotation.concurrent.Immutable; - -import org.sonar.api.scanner.ScannerSide; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.scanner.ScannerSide; import org.sonar.api.server.ServerSide; import org.sonar.api.utils.Version; import org.sonarsource.api.sonarlint.SonarLintSide; @@ -53,7 +52,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * // @since 6.1 * public void bar(); * } - * + * * // Plugin extension * public class MyExtension { * private final SonarRuntime sonarRuntime; @@ -77,7 +76,7 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * * * <p> - * Note that {@link Sensor} extensions can directly get {@link SonarRuntime} through + * Note that {@link Sensor} extensions can directly get {@link SonarRuntime} through * {@link SensorContext#runtime()}, without using constructor injection: * </p> * <pre> @@ -127,16 +126,17 @@ import org.sonarsource.api.sonarlint.SonarLintSide; * </pre> * * <p> - * As this component was introduced in version 6.0, the pattern described above can't be - * exactly applied when plugin must support version 5.6 Long Term Support. In this case plugin - * should use {@link SonarQubeVersion}, for example through {@link Plugin.Context#getSonarQubeVersion()} or - * {@link SensorContext#getSonarQubeVersion()}. + * As this component was introduced in version 6.0, the pattern described above can't be + * exactly applied when plugin must support version 5.6 Long Term Support. In this case plugin + * should use {@link SonarQubeVersion}, for example through {@link Plugin.Context#getSonarQubeVersion()} or + * {@link SensorContext#getSonarQubeVersion()}. * </p> * * <p> * Unit tests of plugin extensions can create instances of {@link SonarRuntime} * via {@link org.sonar.api.internal.SonarRuntimeImpl}. * </p> + * * @since 6.0 */ @ScannerSide @@ -153,19 +153,29 @@ public interface SonarRuntime { * <br/> * Since 6.3, the returned version includes the build number in the fourth field, for * example {@code "6.3.0.12345"}. - */ + */ Version getApiVersion(); /** * The product being executed at runtime. It targets analysers so that they can implement - * different behaviours in SonarQube and SonarLint. + * different behaviours in SonarQube/SonarCloud and SonarLint. */ SonarProduct getProduct(); /** - * The SonarQube stack being executed at runtime. + * The SonarQube/SonarCloud stack being executed at runtime. + * * @throws UnsupportedOperationException if {@link #getProduct()} is not equal to {@link SonarProduct#SONARQUBE} */ SonarQubeSide getSonarQubeSide(); + /** + * The SonarQube/SonarCloud edition being executed at runtime. + * Note that there is a specific edition for SonarCloud. + * + * @throws UnsupportedOperationException if {@link #getProduct()} is not equal to {@link SonarProduct#SONARQUBE} + * @since 7.8 + */ + SonarEdition getEdition(); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java index 0ee4c211f7b..edf595685d4 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java @@ -80,7 +80,7 @@ import org.sonar.api.config.Configuration; import org.sonar.api.config.Settings; import org.sonar.api.config.internal.ConfigurationBridge; import org.sonar.api.config.internal.MapSettings; -import org.sonar.api.internal.ApiVersion; +import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.measures.Metric; import org.sonar.api.scanner.fs.InputProject; @@ -121,7 +121,7 @@ public class SensorContextTester implements SensorContext { this.sensorStorage = new InMemorySensorStorage(); this.project = new DefaultInputProject(ProjectDefinition.create().setKey("projectKey").setBaseDir(moduleBaseDir.toFile()).setWorkDir(moduleBaseDir.resolve(".sonar").toFile())); this.module = new DefaultInputModule(ProjectDefinition.create().setKey("projectKey").setBaseDir(moduleBaseDir.toFile()).setWorkDir(moduleBaseDir.resolve(".sonar").toFile())); - this.runtime = SonarRuntimeImpl.forSonarQube(ApiVersion.load(System2.INSTANCE), SonarQubeSide.SCANNER); + this.runtime = SonarRuntimeImpl.forSonarQube(MetadataLoader.loadVersion(System2.INSTANCE), SonarQubeSide.SCANNER, MetadataLoader.loadEdition(System2.INSTANCE)); } public static SensorContextTester create(File moduleBaseDir) { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java new file mode 100644 index 00000000000..d22a4ec2aa6 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/MetadataLoader.java @@ -0,0 +1,77 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 SonarSource SA + * mailto:info 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.internal; + +import com.google.common.io.Resources; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import org.sonar.api.SonarEdition; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.Version; + +import static org.apache.commons.lang.StringUtils.trimToEmpty; + +/** + * For internal use + * + * @since 7.8 + */ +public class MetadataLoader { + + private static final String VERSION_FILE_PATH = "/sonar-api-version.txt"; + private static final String EDITION_FILE_PATH = "/sonar-edition.txt"; + + private MetadataLoader() { + // only static methods + } + + public static Version loadVersion(System2 system) { + try { + URL url = system.getResource(VERSION_FILE_PATH); + String versionInFile = Resources.toString(url, StandardCharsets.UTF_8); + return Version.parse(versionInFile); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + VERSION_FILE_PATH + " from classpath", e); + } + } + + public static SonarEdition loadEdition(System2 system) { + try { + URL url = system.getResource(EDITION_FILE_PATH); + if (url == null) { + return SonarEdition.COMMUNITY; + } + String editionInFile = Resources.toString(url, StandardCharsets.UTF_8); + return parseEdition(editionInFile); + } catch (IOException e) { + throw new IllegalStateException("Can not load " + EDITION_FILE_PATH + " from classpath", e); + } + } + + static SonarEdition parseEdition(String edition) { + String str = trimToEmpty(edition.toUpperCase()); + try { + return SonarEdition.valueOf(str); + } catch (IllegalArgumentException e) { + throw new IllegalStateException(String.format("Invalid edition found in '%s': '%s'", EDITION_FILE_PATH, str)); + } + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java index 6601412ac28..6395546469f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/internal/SonarRuntimeImpl.java @@ -21,6 +21,7 @@ package org.sonar.api.internal; import javax.annotation.Nullable; import javax.annotation.concurrent.Immutable; +import org.sonar.api.SonarEdition; import org.sonar.api.SonarProduct; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarRuntime; @@ -38,10 +39,13 @@ public class SonarRuntimeImpl implements SonarRuntime { private final Version version; private final SonarProduct product; private final SonarQubeSide sonarQubeSide; + private final SonarEdition edition; - private SonarRuntimeImpl(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide) { + private SonarRuntimeImpl(Version version, SonarProduct product, @Nullable SonarQubeSide sonarQubeSide, @Nullable SonarEdition edition) { + this.edition = edition; requireNonNull(product); checkArgument((product == SonarProduct.SONARQUBE) == (sonarQubeSide != null), "sonarQubeSide should be provided only for SonarQube product"); + checkArgument((product == SonarProduct.SONARQUBE) == (edition != null), "edition should be provided only for SonarQube product"); this.version = requireNonNull(version); this.product = product; this.sonarQubeSide = sonarQubeSide; @@ -65,18 +69,26 @@ public class SonarRuntimeImpl implements SonarRuntime { return sonarQubeSide; } + @Override + public SonarEdition getEdition() { + if (sonarQubeSide == null) { + throw new UnsupportedOperationException("Can only be called in SonarQube"); + } + return edition; + } + /** * Create an instance for SonarQube runtime environment. */ - public static SonarRuntime forSonarQube(Version version, SonarQubeSide side) { - return new SonarRuntimeImpl(version, SonarProduct.SONARQUBE, side); + public static SonarRuntime forSonarQube(Version version, SonarQubeSide side, SonarEdition edition) { + return new SonarRuntimeImpl(version, SonarProduct.SONARQUBE, side, edition); } /** * Create an instance for SonarLint runtime environment. */ public static SonarRuntime forSonarLint(Version version) { - return new SonarRuntimeImpl(version, SonarProduct.SONARLINT, null); + return new SonarRuntimeImpl(version, SonarProduct.SONARLINT, null, null); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java index 70064a5b00c..53b84c86164 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/PluginTest.java @@ -34,7 +34,7 @@ public class PluginTest { @Test public void test_context() { - SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(VERSION_5_6, SonarQubeSide.SERVER); + SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(VERSION_5_6, SonarQubeSide.SERVER, SonarEdition.COMMUNITY); MapSettings settings = new MapSettings().setProperty("foo", "bar"); Plugin.Context context = new PluginContextImpl.Builder() .setSonarRuntime(runtime) diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/MetadataLoaderTest.java index 4013878e9dd..d62ebdcf762 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/internal/ApiVersionTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/internal/MetadataLoaderTest.java @@ -20,6 +20,8 @@ package org.sonar.api.internal; import java.io.File; +import java.net.MalformedURLException; +import org.sonar.api.SonarEdition; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -28,29 +30,50 @@ import org.sonar.api.utils.Version; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class ApiVersionTest { +public class MetadataLoaderTest { + private System2 system = mock(System2.class); @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void load_version_from_file_in_classpath() { - Version version = ApiVersion.load(System2.INSTANCE); + Version version = MetadataLoader.loadVersion(System2.INSTANCE); assertThat(version).isNotNull(); assertThat(version.major()).isGreaterThanOrEqualTo(5); } @Test + public void load_edition_from_file_in_classpath() { + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + assertThat(edition).isNotNull(); + } + + @Test + public void load_edition_defaults_to_community_if_file_not_found() throws MalformedURLException { + when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + assertThat(edition).isEqualTo(SonarEdition.COMMUNITY); + } + + @Test + public void throw_ISE_if_edition_is_invalid() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage("Invalid edition found in '/sonar-edition.txt': 'TRASH'"); + + MetadataLoader.parseEdition("trash"); + } + + @Test public void throw_ISE_if_fail_to_load_version() throws Exception { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Can not load /sonar-api-version.txt from classpath"); - System2 system = spy(System2.class); when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL()); - ApiVersion.load(system); + MetadataLoader.loadVersion(system); } } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java index 5179ef530d9..8e439af9339 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/internal/SonarRuntimeImplTest.java @@ -19,6 +19,7 @@ */ package org.sonar.api.internal; +import org.sonar.api.SonarEdition; import org.assertj.core.api.Assertions; import org.junit.Rule; import org.junit.Test; @@ -30,7 +31,6 @@ import org.sonar.api.utils.Version; import static org.assertj.core.api.Assertions.assertThat; - public class SonarRuntimeImplTest { private static final Version A_VERSION = Version.parse("6.0"); @@ -40,7 +40,7 @@ public class SonarRuntimeImplTest { @Test public void sonarQube_environment() { - SonarRuntime apiVersion = SonarRuntimeImpl.forSonarQube(A_VERSION, SonarQubeSide.SCANNER); + SonarRuntime apiVersion = SonarRuntimeImpl.forSonarQube(A_VERSION, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); assertThat(apiVersion.getApiVersion()).isEqualTo(A_VERSION); assertThat(apiVersion.getProduct()).isEqualTo(SonarProduct.SONARQUBE); assertThat(apiVersion.getSonarQubeSide()).isEqualTo(SonarQubeSide.SCANNER); @@ -60,10 +60,8 @@ public class SonarRuntimeImplTest { } @Test(expected = IllegalArgumentException.class) - public void sonarqube_requires_side() throws Exception { - SonarRuntimeImpl.forSonarQube(A_VERSION, null); + public void sonarqube_requires_side() { + SonarRuntimeImpl.forSonarQube(A_VERSION, null, null); } - - } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java index 302f263a92f..690509a8daa 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java @@ -22,12 +22,13 @@ package org.sonar.scanner.bootstrap; import java.time.Clock; import java.util.List; import java.util.Map; +import org.sonar.api.SonarEdition; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; import org.sonar.api.Plugin; import org.sonar.api.SonarQubeSide; import org.sonar.api.SonarQubeVersion; -import org.sonar.api.internal.ApiVersion; +import org.sonar.api.internal.MetadataLoader; import org.sonar.api.internal.SonarRuntimeImpl; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.System2; @@ -78,7 +79,9 @@ public class GlobalContainer extends ComponentContainer { } private void addBootstrapComponents() { - Version apiVersion = ApiVersion.load(System2.INSTANCE); + Version apiVersion = MetadataLoader.loadVersion(System2.INSTANCE); + SonarEdition edition = MetadataLoader.loadEdition(System2.INSTANCE); + LOG.debug("{} {}", edition.getLabel(), apiVersion); add( // plugins ScannerPluginRepository.class, @@ -88,7 +91,7 @@ public class GlobalContainer extends ComponentContainer { ExtensionInstaller.class, new SonarQubeVersion(apiVersion), - SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER), + SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER, edition), new GlobalServerSettingsProvider(), new GlobalConfigurationProvider(), new ScannerWsClientProvider(), diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java index 9b1db0a0229..a9283aa8590 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/platform/DefaultServerTest.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.platform; +import org.sonar.api.SonarEdition; import org.junit.Test; import org.sonar.api.CoreProperties; import org.sonar.api.SonarQubeSide; @@ -42,7 +43,8 @@ public class DefaultServerTest { ScannerWsClient client = mock(ScannerWsClient.class); when(client.baseUrl()).thenReturn("http://foo.com"); - DefaultServer metadata = new DefaultServer(((MapSettings) settings).asConfig(), client, SonarRuntimeImpl.forSonarQube(Version.parse("2.2"), SonarQubeSide.SCANNER)); + DefaultServer metadata = new DefaultServer(((MapSettings) settings).asConfig(), client, + SonarRuntimeImpl.forSonarQube(Version.parse("2.2"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY)); assertThat(metadata.getId()).isEqualTo("123"); assertThat(metadata.getVersion()).isEqualTo("2.2"); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java index e34193358b2..9808538b302 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/ModuleSensorContextTest.java @@ -19,6 +19,7 @@ */ package org.sonar.scanner.sensor; +import org.sonar.api.SonarEdition; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -66,7 +67,7 @@ public class ModuleSensorContextTest { when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION); settings = new MapSettings(); sensorStorage = mock(SensorStorage.class); - runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER); + runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER, SonarEdition.COMMUNITY); adaptor = new ModuleSensorContext(mock(DefaultInputProject.class), mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, sensorStorage, runtime); } |