Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

UpgradesAction.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.platform.ws;
  21. import com.google.common.io.Resources;
  22. import java.util.List;
  23. import java.util.Optional;
  24. import org.sonar.api.server.ws.Change;
  25. import org.sonar.api.server.ws.Request;
  26. import org.sonar.api.server.ws.Response;
  27. import org.sonar.api.server.ws.WebService;
  28. import org.sonar.api.utils.text.JsonWriter;
  29. import org.sonar.server.plugins.UpdateCenterMatrixFactory;
  30. import org.sonar.server.ui.VersionFormatter;
  31. import org.sonar.updatecenter.common.Plugin;
  32. import org.sonar.updatecenter.common.Release;
  33. import org.sonar.updatecenter.common.SonarUpdate;
  34. import org.sonar.updatecenter.common.UpdateCenter;
  35. import org.sonar.updatecenter.common.Version;
  36. import static org.apache.commons.lang3.StringUtils.isNotBlank;
  37. import static org.sonar.server.plugins.edition.EditionBundledPlugins.isEditionBundled;
  38. /**
  39. * Implementation of the {@code upgrades} action for the System WebService.
  40. */
  41. public class UpgradesAction implements SystemWsAction {
  42. private static final boolean DO_NOT_FORCE_REFRESH = false;
  43. private static final String ARRAY_UPGRADES = "upgrades";
  44. private static final String PROPERTY_UPDATE_CENTER_LTS = "latestLTS";
  45. private static final String PROPERTY_UPDATE_CENTER_LTA = "latestLTA";
  46. private static final String PROPERTY_UPDATE_CENTER_REFRESH = "updateCenterRefresh";
  47. private static final String PROPERTY_VERSION = "version";
  48. private static final String PROPERTY_DESCRIPTION = "description";
  49. private static final String PROPERTY_RELEASE_DATE = "releaseDate";
  50. private static final String PROPERTY_CHANGE_LOG_URL = "changeLogUrl";
  51. private static final String PROPERTY_COMMUNITY_DOWNLOAD_URL = "downloadUrl";
  52. private static final String PROPERTY_DEVELOPER_DOWNLOAD_URL = "downloadDeveloperUrl";
  53. private static final String PROPERTY_ENTERPRISE_DOWNLOAD_URL = "downloadEnterpriseUrl";
  54. private static final String PROPERTY_DATACENTER_DOWNLOAD_URL = "downloadDatacenterUrl";
  55. private static final String OBJECT_PLUGINS = "plugins";
  56. private static final String ARRAY_REQUIRE_UPDATE = "requireUpdate";
  57. private static final String ARRAY_INCOMPATIBLE = "incompatible";
  58. private static final String PROPERTY_KEY = "key";
  59. private static final String PROPERTY_NAME = "name";
  60. private static final String PROPERTY_LICENSE = "license";
  61. private static final String PROPERTY_CATEGORY = "category";
  62. private static final String PROPERTY_ORGANIZATION_NAME = "organizationName";
  63. private static final String PROPERTY_ORGANIZATION_URL = "organizationUrl";
  64. private static final String PROPERTY_HOMEPAGE_URL = "homepageUrl";
  65. private static final String PROPERTY_ISSUE_TRACKER_URL = "issueTrackerUrl";
  66. private static final String PROPERTY_EDITION_BUNDLED = "editionBundled";
  67. private static final String PROPERTY_TERMS_AND_CONDITIONS_URL = "termsAndConditionsUrl";
  68. public static final String INSTALLED_VERSION_ACTIVE = "installedVersionActive";
  69. private final UpdateCenterMatrixFactory updateCenterFactory;
  70. private final ActiveVersionEvaluator activeVersionEvaluator;
  71. public UpgradesAction(UpdateCenterMatrixFactory updateCenterFactory, ActiveVersionEvaluator activeVersionEvaluator) {
  72. this.updateCenterFactory = updateCenterFactory;
  73. this.activeVersionEvaluator = activeVersionEvaluator;
  74. }
  75. private static void writeMetadata(JsonWriter jsonWriter, Release release) {
  76. jsonWriter.prop(PROPERTY_VERSION, VersionFormatter.format(release.getVersion().getName()));
  77. jsonWriter.prop(PROPERTY_DESCRIPTION, release.getDescription());
  78. jsonWriter.propDate(PROPERTY_RELEASE_DATE, release.getDate());
  79. jsonWriter.prop(PROPERTY_CHANGE_LOG_URL, release.getChangelogUrl());
  80. jsonWriter.prop(PROPERTY_COMMUNITY_DOWNLOAD_URL, release.getDownloadUrl(Release.Edition.COMMUNITY));
  81. jsonWriter.prop(PROPERTY_DEVELOPER_DOWNLOAD_URL, release.getDownloadUrl(Release.Edition.DEVELOPER));
  82. jsonWriter.prop(PROPERTY_ENTERPRISE_DOWNLOAD_URL, release.getDownloadUrl(Release.Edition.ENTERPRISE));
  83. jsonWriter.prop(PROPERTY_DATACENTER_DOWNLOAD_URL, release.getDownloadUrl(Release.Edition.DATACENTER));
  84. }
  85. @Override
  86. public void define(WebService.NewController controller) {
  87. controller.createAction("upgrades")
  88. .setDescription("Lists available upgrades for the SonarQube instance (if any) and for each one, " +
  89. "lists incompatible plugins and plugins requiring upgrade." +
  90. "<br/>" +
  91. "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed " +
  92. "is provided in the response.")
  93. .setSince("5.2")
  94. .setHandler(this)
  95. .setResponseExample(Resources.getResource(this.getClass(), "example-upgrades_plugins.json"))
  96. .setChangelog(new Change("10.5", "The field 'ltsVersion' is deprecated from the response"))
  97. .setChangelog(new Change("10.5", "The field 'ltaVersion' is added to indicate the Long-Term Active Version"))
  98. .setChangelog(new Change("10.5", "The field 'installedVersionActive' is added to indicate if the installed version is an active version"));
  99. }
  100. @Override
  101. public void handle(Request request, Response response) throws Exception {
  102. try (JsonWriter jsonWriter = response.newJsonWriter()) {
  103. jsonWriter.setSerializeEmptys(false);
  104. writeResponse(jsonWriter);
  105. }
  106. }
  107. private void writeResponse(JsonWriter jsonWriter) {
  108. jsonWriter.beginObject();
  109. Optional<UpdateCenter> updateCenterOpt = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
  110. writeUpgrades(jsonWriter, updateCenterOpt);
  111. if (updateCenterOpt.isPresent()) {
  112. UpdateCenter updateCenter = updateCenterOpt.get();
  113. writeLatestLtsVersion(jsonWriter, updateCenter);
  114. writeLatestLtaVersion(jsonWriter, updateCenter);
  115. jsonWriter.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.getDate());
  116. jsonWriter.prop(INSTALLED_VERSION_ACTIVE, activeVersionEvaluator.evaluateIfActiveVersion(updateCenter));
  117. }
  118. jsonWriter.endObject();
  119. }
  120. private static void writeLatestLtsVersion(JsonWriter jsonWriter, UpdateCenter updateCenter) {
  121. Release ltsRelease = updateCenter.getSonar().getLtsRelease();
  122. if (ltsRelease != null) {
  123. Version ltsVersion = ltsRelease.getVersion();
  124. String latestLTS = String.format("%s.%s", ltsVersion.getMajor(), ltsVersion.getMinor());
  125. jsonWriter.prop(PROPERTY_UPDATE_CENTER_LTS, latestLTS);
  126. }
  127. }
  128. private static void writeLatestLtaVersion(JsonWriter jsonWriter, UpdateCenter updateCenter) {
  129. Release ltaRelease = updateCenter.getSonar().getLtaVersion();
  130. if (ltaRelease != null) {
  131. Version ltaVersion = ltaRelease.getVersion();
  132. String latestLTA = String.format("%s.%s", ltaVersion.getMajor(), ltaVersion.getMinor());
  133. jsonWriter.prop(PROPERTY_UPDATE_CENTER_LTA, latestLTA);
  134. }
  135. }
  136. private static void writeUpgrades(JsonWriter jsonWriter, Optional<UpdateCenter> updateCenter) {
  137. jsonWriter.name(ARRAY_UPGRADES).beginArray();
  138. if (updateCenter.isPresent()) {
  139. for (SonarUpdate sonarUpdate : updateCenter.get().findSonarUpdates()) {
  140. writeUpgrade(jsonWriter, sonarUpdate);
  141. }
  142. }
  143. jsonWriter.endArray();
  144. }
  145. private static void writeUpgrade(JsonWriter jsonWriter, SonarUpdate sonarUpdate) {
  146. jsonWriter.beginObject();
  147. writeMetadata(jsonWriter, sonarUpdate.getRelease());
  148. writePlugins(jsonWriter, sonarUpdate);
  149. jsonWriter.endObject();
  150. }
  151. private static void writePlugins(JsonWriter jsonWriter, SonarUpdate sonarUpdate) {
  152. jsonWriter.name(OBJECT_PLUGINS).beginObject();
  153. writePluginsToUpdate(jsonWriter, sonarUpdate.getPluginsToUpgrade());
  154. writeIncompatiblePlugins(jsonWriter, sonarUpdate.getIncompatiblePlugins());
  155. jsonWriter.endObject();
  156. }
  157. private static void writePluginsToUpdate(JsonWriter jsonWriter, List<Release> pluginsToUpgrade) {
  158. jsonWriter.name(ARRAY_REQUIRE_UPDATE).beginArray();
  159. for (Release release : pluginsToUpgrade) {
  160. jsonWriter.beginObject();
  161. writePlugin(jsonWriter, (Plugin) release.getArtifact());
  162. String version = isNotBlank(release.getDisplayVersion()) ? release.getDisplayVersion() : release.getVersion().toString();
  163. jsonWriter.prop(PROPERTY_VERSION, version);
  164. jsonWriter.endObject();
  165. }
  166. jsonWriter.endArray();
  167. }
  168. private static void writeIncompatiblePlugins(JsonWriter jsonWriter, List<Plugin> incompatiblePlugins) {
  169. jsonWriter.name(ARRAY_INCOMPATIBLE).beginArray();
  170. for (Plugin incompatiblePlugin : incompatiblePlugins) {
  171. jsonWriter.beginObject();
  172. writePlugin(jsonWriter, incompatiblePlugin);
  173. jsonWriter.endObject();
  174. }
  175. jsonWriter.endArray();
  176. }
  177. public static void writePlugin(JsonWriter jsonWriter, Plugin plugin) {
  178. jsonWriter.prop(PROPERTY_KEY, plugin.getKey());
  179. jsonWriter.prop(PROPERTY_NAME, plugin.getName());
  180. jsonWriter.prop(PROPERTY_CATEGORY, plugin.getCategory());
  181. jsonWriter.prop(PROPERTY_DESCRIPTION, plugin.getDescription());
  182. jsonWriter.prop(PROPERTY_LICENSE, plugin.getLicense());
  183. jsonWriter.prop(PROPERTY_TERMS_AND_CONDITIONS_URL, plugin.getTermsConditionsUrl());
  184. jsonWriter.prop(PROPERTY_ORGANIZATION_NAME, plugin.getOrganization());
  185. jsonWriter.prop(PROPERTY_ORGANIZATION_URL, plugin.getOrganizationUrl());
  186. jsonWriter.prop(PROPERTY_HOMEPAGE_URL, plugin.getHomepageUrl());
  187. jsonWriter.prop(PROPERTY_ISSUE_TRACKER_URL, plugin.getIssueTrackerUrl());
  188. jsonWriter.prop(PROPERTY_EDITION_BUNDLED, isEditionBundled(plugin));
  189. }
  190. }