From 825d006b31a2e3eb8d99d1108558c3442c0cd6ad Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Mon, 20 Apr 2015 12:31:52 +0200 Subject: [PATCH] SONAR-6383 add more info to JSON response of WS pending plugins now display as much info on plugins as there is in response of WS installed plugins thanks to META-INF information in jar files --- .../plugins/ws/InstalledPluginsWsAction.java | 2 +- .../plugins/ws/PendingPluginsWsAction.java | 52 +++++++-- .../plugins/ws/example-pending_plugins.json | 33 +++++- .../ws/PendingPluginsWsActionTest.java | 101 ++++++++++++------ 4 files changed, 143 insertions(+), 45 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java index 0a904d4463b..a93bf04e013 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledPluginsWsAction.java @@ -56,7 +56,7 @@ public class InstalledPluginsWsAction implements PluginsWsAction { private final PluginRepository pluginRepository; - private static final Ordering NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural() + public static final Ordering NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural() .onResultOf(PluginMetadataToName.INSTANCE) .compound(Ordering.natural().onResultOf(PluginMetadataToKey.INSTANCE)); diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java index 9c9d6be3f4a..22147405287 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingPluginsWsAction.java @@ -19,16 +19,21 @@ */ package org.sonar.server.plugins.ws; -import com.google.common.io.Resources; +import org.sonar.api.platform.PluginMetadata; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.plugins.DefaultPluginMetadata; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.ServerPluginJarsInstaller; +import java.util.Collection; +import java.util.List; + import static com.google.common.collect.ImmutableSortedSet.copyOf; -import static java.lang.String.CASE_INSENSITIVE_ORDER; +import static com.google.common.io.Resources.getResource; +import static org.sonar.server.plugins.ws.InstalledPluginsWsAction.NAME_KEY_PLUGIN_METADATA_COMPARATOR; /** * Implementation of the {@code pending} action for the Plugins WebService. @@ -54,7 +59,7 @@ public class PendingPluginsWsAction implements PluginsWsAction { .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by archive name") .setSince("5.2") .setHandler(this) - .setResponseExample(Resources.getResource(this.getClass(), "example-pending_plugins.json")); + .setResponseExample(getResource(this.getClass(), "example-pending_plugins.json")); } @Override @@ -74,8 +79,9 @@ public class PendingPluginsWsAction implements PluginsWsAction { private void writeInstalling(JsonWriter jsonWriter) { jsonWriter.name(ARRAY_INSTALLING); jsonWriter.beginArray(); - for (String fileName : copyOf(CASE_INSENSITIVE_ORDER, pluginDownloader.getDownloadedPluginFilenames())) { - writeArchive(jsonWriter, fileName); + List plugins = pluginDownloader.getDownloadedPlugins(); + for (PluginMetadata pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { + writePlugin(jsonWriter, pluginMetadata); } jsonWriter.endArray(); } @@ -83,18 +89,44 @@ public class PendingPluginsWsAction implements PluginsWsAction { private void writeRemoving(JsonWriter jsonWriter) { jsonWriter.name(ARRAY_REMOVING); jsonWriter.beginArray(); - for (String fileName : copyOf(CASE_INSENSITIVE_ORDER, serverPluginJarsInstaller.getUninstalledPluginFilenames())) { - writeArchive(jsonWriter, fileName); + Collection plugins = serverPluginJarsInstaller.getUninstalledPlugins(); + for (PluginMetadata pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) { + writePlugin(jsonWriter, pluginMetadata); } jsonWriter.endArray(); } - private void writeArchive(JsonWriter jsonWriter, String fileName) { + private void writePlugin(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { jsonWriter.beginObject(); + + writeMetadata(jsonWriter, pluginMetadata); + + jsonWriter.prop("homepageUrl", pluginMetadata.getHomepage()); + jsonWriter.prop("issueTrackerUrl", pluginMetadata.getIssueTrackerUrl()); + + writeArchive(jsonWriter, pluginMetadata); + + jsonWriter.endObject(); + } + + private void writeMetadata(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { + jsonWriter.prop("key", pluginMetadata.getKey()); + jsonWriter.prop("name", pluginMetadata.getName()); + jsonWriter.prop("description", pluginMetadata.getDescription()); + jsonWriter.prop("version", pluginMetadata.getVersion()); + jsonWriter.prop("license", pluginMetadata.getLicense()); + jsonWriter.prop("organizationName", pluginMetadata.getOrganization()); + jsonWriter.prop("organizationUrl", pluginMetadata.getOrganizationUrl()); + } + + private void writeArchive(JsonWriter jsonWriter, PluginMetadata pluginMetadata) { + if (pluginMetadata.getFile() == null) { + return; + } + jsonWriter.name(OBJECT_ARTIFACT); jsonWriter.beginObject(); - jsonWriter.prop(PROPERTY_NAME, fileName); - jsonWriter.endObject(); + jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getFile().getName()); jsonWriter.endObject(); } } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json b/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json index bddbe32535c..841fd21996e 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/plugins/ws/example-pending_plugins.json @@ -2,21 +2,48 @@ "installing": [ { + "key": "scmgit", + "name": "Git", + "description": "Git SCM Provider.", + "version": "1.0", + "license": "GNU LGPL 3", + "organizationName": "SonarSource", + "organizationUrl": "http://www.sonarsource.com", + "homepageUrl": "http://redirect.sonarsource.com/plugins/scmgit.html", + "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARSCGIT", "artifact": { - "name": "findbugs-2.1.jar" + "name": "sonar-scm-git-plugin-1.0.jar" } }, { + "key": "java", + "name": "Java", + "description": "SonarQube rule engine.", + "version": "3.0", + "license": "GNU LGPL 3", + "organizationName": "SonarSource", + "organizationUrl": "http://www.sonarsource.com", + "homepageUrl": "http://redirect.sonarsource.com/plugins/java.html", + "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARJAVA", "artifact": { - "name": "jira-2.6.jar" + "name": "sonar-java-plugin-3.0.jar" } } ], "removing": [ { + "key": "scmsvn", + "name": "SVN", + "description": "SVN SCM Provider.", + "version": "1.0", + "license": "GNU LGPL 3", + "organizationName": "SonarSource", + "organizationUrl": "http://www.sonarsource.com", + "homepageUrl": "http://redirect.sonarsource.com/plugins/scmsvn.html", + "issueTrackerUrl": "http://jira.codehaus.org/browse/SONARSCSVN", "artifact": { - "name": "pmd-2.1.jar" + "name": "sonar-scm-svn-plugin-1.0.jar" } } ] diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java index 240c6a56621..5d3f544bab9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingPluginsWsActionTest.java @@ -22,19 +22,36 @@ package org.sonar.server.plugins.ws; import org.junit.Test; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; +import org.sonar.core.plugins.DefaultPluginMetadata; import org.sonar.server.plugins.PluginDownloader; import org.sonar.server.plugins.ServerPluginJarsInstaller; import org.sonar.server.ws.WsTester; +import java.io.File; + import static com.google.common.collect.ImmutableList.of; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.sonar.core.plugins.DefaultPluginMetadata.create; import static org.sonar.test.JsonAssert.assertJson; public class PendingPluginsWsActionTest { + public static final DefaultPluginMetadata GIT_PLUGIN_METADATA = create("scmgit") + .setName("Git") + .setDescription("Git SCM Provider.") + .setVersion("1.0") + .setLicense("GNU LGPL 3") + .setOrganization("SonarSource") + .setOrganizationUrl("http://www.sonarsource.com") + .setHomepage("http://redirect.sonarsource.com/plugins/scmgit.html") + .setIssueTrackerUrl("http://jira.codehaus.org/browse/SONARSCGIT") + .setFile(new File("/home/user/sonar-scm-git-plugin-1.0.jar")); private static final String DUMMY_CONTROLLER_KEY = "dummy"; + public static final DefaultPluginMetadata PLUGIN_2_2 = create("key2").setName("name2"); + public static final DefaultPluginMetadata PLUGIN_2_1 = create("key1").setName("name2"); + public static final DefaultPluginMetadata PLUGIN_0_0 = create("key0").setName("name0"); private PluginDownloader pluginDownloader = mock(PluginDownloader.class); private ServerPluginJarsInstaller serverPluginJarsInstaller = mock(ServerPluginJarsInstaller.class); @@ -74,7 +91,7 @@ public class PendingPluginsWsActionTest { @Test public void verify_properties_displayed_in_json_per_installing_plugin() throws Exception { - when(pluginDownloader.getDownloadedPluginFilenames()).thenReturn(of("installed_file.jar")); + when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(GIT_PLUGIN_METADATA)); underTest.handle(request, response); @@ -83,8 +100,17 @@ public class PendingPluginsWsActionTest { " \"installing\": " + " [" + " {" + + " \"key\": \"scmgit\"," + + " \"name\": \"Git\"," + + " \"description\": \"Git SCM Provider.\"," + + " \"version\": \"1.0\"," + + " \"license\": \"GNU LGPL 3\"," + + " \"organizationName\": \"SonarSource\"," + + " \"organizationUrl\": \"http://www.sonarsource.com\"," + + " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + " \"artifact\": {" + - " \"name\": \"installed_file.jar\"" + + " \"name\": \"sonar-scm-git-plugin-1.0.jar\"" + " }" + " }" + " ]," + @@ -95,7 +121,7 @@ public class PendingPluginsWsActionTest { @Test public void verify_properties_displayed_in_json_per_removing_plugin() throws Exception { - when(serverPluginJarsInstaller.getUninstalledPluginFilenames()).thenReturn(of("removed_file.jar")); + when(serverPluginJarsInstaller.getUninstalledPlugins()).thenReturn(of(GIT_PLUGIN_METADATA)); underTest.handle(request, response); @@ -105,8 +131,17 @@ public class PendingPluginsWsActionTest { " \"removing\": " + " [" + " {" + + " \"key\": \"scmgit\"," + + " \"name\": \"Git\"," + + " \"description\": \"Git SCM Provider.\"," + + " \"version\": \"1.0\"," + + " \"license\": \"GNU LGPL 3\"," + + " \"organizationName\": \"SonarSource\"," + + " \"organizationUrl\": \"http://www.sonarsource.com\"," + + " \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," + + " \"issueTrackerUrl\": \"http://jira.codehaus.org/browse/SONARSCGIT\"," + " \"artifact\": {" + - " \"name\": \"removed_file.jar\"" + + " \"name\": \"sonar-scm-git-plugin-1.0.jar\"" + " }" + " }" + " ]" + @@ -115,8 +150,13 @@ public class PendingPluginsWsActionTest { } @Test - public void installing_plugin_are_sorted_and_unique() throws Exception { - when(pluginDownloader.getDownloadedPluginFilenames()).thenReturn(of("file2.jar", "file0.jar", "file0.jar", "file1.jar")); + public void installing_plugin_are_sorted_by_name_then_key_and_are_unique() throws Exception { + when(pluginDownloader.getDownloadedPlugins()).thenReturn(of( + PLUGIN_2_2, + PLUGIN_2_1, + PLUGIN_2_2, + PLUGIN_0_0 + )); underTest.handle(request, response); @@ -125,19 +165,16 @@ public class PendingPluginsWsActionTest { " \"installing\": " + " [" + " {" + - " \"artifact\": {" + - " \"name\": \"file0.jar\"" + - " }" + + " \"key\": \"key0\"," + + " \"name\": \"name0\"," + " }," + " {" + - " \"artifact\": {" + - " \"name\": \"file1.jar\"" + - " }" + + " \"key\": \"key1\"," + + " \"name\": \"name2\"," + " }," + " {" + - " \"artifact\": {" + - " \"name\": \"file2.jar\"" + - " }" + + " \"key\": \"key2\"," + + " \"name\": \"name2\"," + " }" + " ]," + " \"removing\": []" + @@ -147,7 +184,12 @@ public class PendingPluginsWsActionTest { @Test public void removing_plugin_are_sorted_and_unique() throws Exception { - when(serverPluginJarsInstaller.getUninstalledPluginFilenames()).thenReturn(of("file2.jar", "file0.jar", "file0.jar", "file1.jar")); + when(serverPluginJarsInstaller.getUninstalledPlugins()).thenReturn(of( + PLUGIN_2_2, + PLUGIN_2_1, + PLUGIN_2_2, + PLUGIN_0_0 + )); underTest.handle(request, response); @@ -156,21 +198,18 @@ public class PendingPluginsWsActionTest { " \"installing\": []," + " \"removing\": " + " [" + - " {" + - " \"artifact\": {" + - " \"name\": \"file0.jar\"" + - " }" + - " }," + - " {" + - " \"artifact\": {" + - " \"name\": \"file1.jar\"" + - " }" + - " }," + - " {" + - " \"artifact\": {" + - " \"name\": \"file2.jar\"" + - " }" + - " }" + + " {" + + " \"key\": \"key0\"," + + " \"name\": \"name0\"," + + " }," + + " {" + + " \"key\": \"key1\"," + + " \"name\": \"name2\"," + + " }," + + " {" + + " \"key\": \"key2\"," + + " \"name\": \"name2\"," + + " }" + " ]" + "}" ); -- 2.39.5