Skip to content

Commit

Permalink
SONAR-6383 add more info to JSON response of WS pending plugins
Browse files Browse the repository at this point in the history
now display as much info on plugins as there is in response of WS installed plugins thanks to META-INF information in jar files
  • Loading branch information
sns-seb committed Apr 21, 2015
1 parent d465990 commit 825d006
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 45 deletions.
Expand Up @@ -56,7 +56,7 @@ public class InstalledPluginsWsAction implements PluginsWsAction {

private final PluginRepository pluginRepository;

private static final Ordering<PluginMetadata> NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural()
public static final Ordering<PluginMetadata> NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural()
.onResultOf(PluginMetadataToName.INSTANCE)
.compound(Ordering.natural().onResultOf(PluginMetadataToKey.INSTANCE));

Expand Down
Expand Up @@ -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.
Expand All @@ -54,7 +59,7 @@ public void define(WebService.NewController controller) {
.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
Expand All @@ -74,27 +79,54 @@ public void handle(Request request, Response response) throws Exception {
private void writeInstalling(JsonWriter jsonWriter) {
jsonWriter.name(ARRAY_INSTALLING);
jsonWriter.beginArray();
for (String fileName : copyOf(CASE_INSENSITIVE_ORDER, pluginDownloader.getDownloadedPluginFilenames())) {
writeArchive(jsonWriter, fileName);
List<DefaultPluginMetadata> plugins = pluginDownloader.getDownloadedPlugins();
for (PluginMetadata pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) {
writePlugin(jsonWriter, pluginMetadata);
}
jsonWriter.endArray();
}

private void writeRemoving(JsonWriter jsonWriter) {
jsonWriter.name(ARRAY_REMOVING);
jsonWriter.beginArray();
for (String fileName : copyOf(CASE_INSENSITIVE_ORDER, serverPluginJarsInstaller.getUninstalledPluginFilenames())) {
writeArchive(jsonWriter, fileName);
Collection<DefaultPluginMetadata> 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();
}
}
Expand Up @@ -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"
}
}
]
Expand Down
Expand Up @@ -22,19 +22,36 @@
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);
Expand Down Expand Up @@ -74,7 +91,7 @@ public void empty_arrays_are_returned_when_there_nothing_pending() throws Except

@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);

Expand All @@ -83,8 +100,17 @@ public void verify_properties_displayed_in_json_per_installing_plugin() throws E
" \"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\"" +
" }" +
" }" +
" ]," +
Expand All @@ -95,7 +121,7 @@ public void verify_properties_displayed_in_json_per_installing_plugin() throws E

@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);

Expand All @@ -105,8 +131,17 @@ public void verify_properties_displayed_in_json_per_removing_plugin() throws Exc
" \"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\"" +
" }" +
" }" +
" ]" +
Expand All @@ -115,8 +150,13 @@ public void verify_properties_displayed_in_json_per_removing_plugin() throws Exc
}

@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);

Expand All @@ -125,19 +165,16 @@ public void installing_plugin_are_sorted_and_unique() throws Exception {
" \"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\": []" +
Expand All @@ -147,7 +184,12 @@ public void installing_plugin_are_sorted_and_unique() throws Exception {

@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);

Expand All @@ -156,21 +198,18 @@ public void removing_plugin_are_sorted_and_unique() throws Exception {
" \"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\"," +
" }" +
" ]" +
"}"
);
Expand Down

0 comments on commit 825d006

Please sign in to comment.