]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-22018 introduce version EOL to properties, and update GlobalAction
authorOrlovAlexander <35396155+OrlovAlexander85@users.noreply.github.com>
Tue, 9 Apr 2024 13:22:11 +0000 (15:22 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 10 Apr 2024 20:02:53 +0000 (20:02 +0000)
gradle.properties
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/GlobalAction.java
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/global-example.json
server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/GlobalActionTest.java
sonar-plugin-api-impl/build.gradle
sonar-plugin-api-impl/src/main/java/org/sonar/api/internal/MetadataLoader.java
sonar-plugin-api-impl/src/main/resources/sq-version-eol.txt [new file with mode: 0644]
sonar-plugin-api-impl/src/test/java/org/sonar/api/internal/MetadataLoaderTest.java

index 2a0e987ed24bc7af66406b9988faa997cba6c3cc..566cba8aa11f6051f6746be02be12f4517daabde 100644 (file)
@@ -1,5 +1,12 @@
 group=org.sonarsource.sonarqube
 version=9.9.5
+
+# End Of Life date for the version. MMF-3763. format is yyyy-MM-dd
+# 6 months from the release date for non LTA versions
+# 30 months from the release date for LTA versions
+# No change required for patch versions
+versionEOL=2025-08-07
+
 description=Open source platform for continuous inspection of code quality
 projectTitle=SonarQube
 org.gradle.jvmargs=-Xmx2048m
index 1f4f1007ee3dc1ebcc11a649f533c37adc8bd2ff..fb4959fff8b91c6affbdaeeb04b7a4a939336d14 100644 (file)
@@ -28,9 +28,11 @@ import org.sonar.api.config.Configuration;
 import org.sonar.api.platform.Server;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService.NewController;
+import org.sonar.api.utils.System2;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.api.web.page.Page;
 import org.sonar.core.platform.PlatformEditionProvider;
@@ -47,6 +49,7 @@ import org.sonar.server.user.UserSession;
 
 import static org.sonar.api.CoreProperties.DEVELOPER_AGGREGATED_INFO_DISABLED;
 import static org.sonar.api.CoreProperties.RATING_GRID;
+import static org.sonar.api.internal.MetadataLoader.loadSqVersionEol;
 import static org.sonar.core.config.WebConstants.SONAR_LF_ENABLE_GRAVATAR;
 import static org.sonar.core.config.WebConstants.SONAR_LF_GRAVATAR_SERVER_URL;
 import static org.sonar.core.config.WebConstants.SONAR_LF_LOGO_URL;
@@ -112,7 +115,8 @@ public class GlobalAction implements NavigationWsAction, Startable {
       .setHandler(this)
       .setInternal(true)
       .setResponseExample(getClass().getResource("global-example.json"))
-      .setSince("5.2");
+      .setSince("5.2")
+      .setChangelog(new Change("9.9.5", "Field 'versionEOL' added, to indicate the end of support of installed version."));
   }
 
   @Override
@@ -125,6 +129,7 @@ public class GlobalAction implements NavigationWsAction, Startable {
       writeDeprecatedLogoProperties(json);
       writeQualifiers(json);
       writeVersion(json);
+      writeVersionEol(json);
       writeDatabaseProduction(json);
       writeInstanceUsesDefaultAdminCredentials(json);
       editionProvider.get().ifPresent(e -> json.prop("edition", e.name().toLowerCase(Locale.ENGLISH)));
@@ -175,6 +180,10 @@ public class GlobalAction implements NavigationWsAction, Startable {
     json.prop("version", displayVersion);
   }
 
+  private void writeVersionEol(JsonWriter json) {
+    json.prop("versionEOL", loadSqVersionEol(System2.INSTANCE));
+  }
+
   private void writeDatabaseProduction(JsonWriter json) {
     json.prop("productionDatabase", !dbClient.getDatabase().getDialect().getId().equals(H2.ID));
   }
index a1619ee69fd3b9b7a966625869aeced2c5afea1e..ec6d8c052c5016959f357eb1d0a056005758f9a8 100644 (file)
@@ -24,6 +24,7 @@
     "POL"
   ],
   "version": "6.2",
+  "versionEOL": "2025-01-01",
   "productionDatabase": true,
   "canAdmin": false,
   "standalone": true,
index 19a79bf4ec55e7d420040396fac50fcbe15c23bb..c0f77e2a7eab363ee2e09011f4cc0d123409e811 100644 (file)
  */
 package org.sonar.server.ui.ws;
 
+import java.util.Objects;
 import java.util.Optional;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.internal.MapSettings;
+import org.mockito.MockedStatic;
+import org.sonar.api.internal.MetadataLoader;
 import org.sonar.api.platform.Server;
 import org.sonar.api.resources.ResourceType;
 import org.sonar.api.resources.ResourceTypeTree;
@@ -50,6 +53,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.when;
 import static org.sonar.test.JsonAssert.assertJson;
 
@@ -184,6 +188,15 @@ public class GlobalActionTest {
       "}");
   }
 
+  @Test
+  public void execute_shouldReturnVersionEol() {
+    init();
+    try (MockedStatic<MetadataLoader> mocked = mockStatic(MetadataLoader.class)) {
+      mocked.when(() -> MetadataLoader.loadSqVersionEol(any())).thenReturn("2025-01-01");
+      assertThat(call()).contains("\"versionEOL\":\"2025-01-01\"");
+    }
+  }
+
   @Test
   public void functional_version_when_4_digits() {
     init();
@@ -283,8 +296,14 @@ public class GlobalActionTest {
     when(nodeInformation.isStandalone()).thenReturn(true);
     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY));
 
-    String result = call();
-    assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString());
+
+    try (MockedStatic<MetadataLoader> mocked = mockStatic(MetadataLoader.class)) {
+      mocked.when(() -> MetadataLoader.loadSqVersionEol(any())).thenReturn("2025-01-01");
+
+      String result = call();
+
+      assertJson(result).isSimilarTo(Objects.requireNonNull(ws.getDef().responseExampleAsString()));
+    }
   }
 
   @Test
index 51480338d9d88b09877e838757f26ba6acb65720..a55d546a8f6caec54ece70fe265b5a2b71d84216 100644 (file)
@@ -28,7 +28,8 @@ dependencies {
 import org.apache.tools.ant.filters.ReplaceTokens
 processResources {
   filter ReplaceTokens, tokens: [
-          'project.version': project.version
+          'project.version': project.version,
+          'versionEOL': project.properties["versionEOL"]
   ]
 }
 
index e0c75d17013479f1b6b3532e6f5e9e32c1e150d1..16ff62524fa94ba6a5d0a64579717750235576b8 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.SonarEdition;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.Version;
 
+import static java.lang.String.format;
 import static org.apache.commons.lang.StringUtils.trimToEmpty;
 
 /**
@@ -40,6 +41,8 @@ public class MetadataLoader {
   private static final String SQ_VERSION_FILE_PATH = "/sq-version.txt";
   private static final String SONAR_API_VERSION_FILE_PATH = "/sonar-api-version.txt";
   private static final String EDITION_FILE_PATH = "/sonar-edition.txt";
+  private static final String SQ_VERSION_EOL_FILE_PATH = "/sq-version-eol.txt";
+  public static final String CAN_NOT_LOAD_FROM_CLASSPATH = "Can not load %s from classpath";
 
   private MetadataLoader() {
     // only static methods
@@ -48,18 +51,25 @@ public class MetadataLoader {
   public static Version loadApiVersion(System2 system) {
     return getVersion(system, SONAR_API_VERSION_FILE_PATH);
   }
+
   public static Version loadSQVersion(System2 system) {
     return getVersion(system, SQ_VERSION_FILE_PATH);
   }
 
+  public static String loadSqVersionEol(System2 system) {
+    return getParamFromFile(system, SQ_VERSION_EOL_FILE_PATH);
+  }
+
   private static Version getVersion(System2 system, String versionFilePath) {
-    URL url = system.getResource(versionFilePath);
+    return Version.parse(getParamFromFile(system, versionFilePath));
+  }
 
-    try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.name())) {
-      String versionInFile = scanner.nextLine();
-      return Version.parse(versionInFile);
+  private static String getParamFromFile(System2 system, String filePath) {
+    URL url = system.getResource(filePath);
+    try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8)) {
+      return scanner.nextLine();
     } catch (IOException e) {
-      throw new IllegalStateException("Can not load " + versionFilePath + " from classpath ", e);
+      throw new IllegalStateException(format(CAN_NOT_LOAD_FROM_CLASSPATH, filePath), e);
     }
   }
 
@@ -68,11 +78,11 @@ public class MetadataLoader {
     if (url == null) {
       return SonarEdition.COMMUNITY;
     }
-    try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.name())) {
+    try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8)) {
       String editionInFile = scanner.nextLine();
       return parseEdition(editionInFile);
     } catch (IOException e) {
-      throw new IllegalStateException("Can not load " + EDITION_FILE_PATH + " from classpath", e);
+      throw new IllegalStateException(format(CAN_NOT_LOAD_FROM_CLASSPATH, EDITION_FILE_PATH), e);
     }
   }
 
@@ -81,7 +91,7 @@ public class MetadataLoader {
     try {
       return SonarEdition.valueOf(str);
     } catch (IllegalArgumentException e) {
-      throw new IllegalStateException(String.format("Invalid edition found in '%s': '%s'", EDITION_FILE_PATH, str));
+      throw new IllegalStateException(format("Invalid edition found in '%s': '%s'", EDITION_FILE_PATH, str));
     }
   }
 }
diff --git a/sonar-plugin-api-impl/src/main/resources/sq-version-eol.txt b/sonar-plugin-api-impl/src/main/resources/sq-version-eol.txt
new file mode 100644 (file)
index 0000000..154f932
--- /dev/null
@@ -0,0 +1 @@
+@versionEOL@
index 3ee4ec5df9a59fe5b69a4cfc1347b70da78b3826..31628e5ebda0db8d11463887d727dd39795cb8f3 100644 (file)
@@ -78,4 +78,17 @@ public class MetadataLoaderTest {
       .hasMessageContaining("Can not load /sonar-api-version.txt from classpath");
   }
 
+  @Test
+  public void loadSqVersionEol_shouldLoadCorrectEol() {
+    String eol = MetadataLoader.loadSqVersionEol(System2.INSTANCE);
+    assertThat(eol).isNotNull();
+  }
+
+  @Test
+  public void loadSqVersionEol_whenFileNotFound_shouldThrowException() throws MalformedURLException {
+    when(system.getResource(anyString())).thenReturn(new File("target/unknown").toURI().toURL());
+    assertThatThrownBy(() -> MetadataLoader.loadSqVersionEol(system))
+      .isInstanceOf(IllegalStateException.class)
+      .hasMessageContaining("Can not load /sq-version-eol.txt from classpath");
+  }
 }