Skip to content

Commit

Permalink
SONAR-7591 Make category an optional field in WS api/plugins/installed
Browse files Browse the repository at this point in the history
  • Loading branch information
teryk committed May 11, 2016
1 parent 1c5c7dc commit cb09371
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 14 deletions.
Expand Up @@ -19,9 +19,11 @@
*/ */
package org.sonar.server.plugins.ws; package org.sonar.server.plugins.ws;


import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.Response;
Expand All @@ -33,6 +35,8 @@
import org.sonar.updatecenter.common.Plugin; import org.sonar.updatecenter.common.Plugin;


import static com.google.common.collect.ImmutableSortedSet.copyOf; import static com.google.common.collect.ImmutableSortedSet.copyOf;
import static java.lang.String.format;
import static java.util.Collections.singleton;
import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR; import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR;
import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey; import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey;


Expand All @@ -41,6 +45,7 @@
*/ */
public class InstalledAction implements PluginsWsAction { public class InstalledAction implements PluginsWsAction {
private static final String ARRAY_PLUGINS = "plugins"; private static final String ARRAY_PLUGINS = "plugins";
private static final String FIELD_CATEGORY = "category";


private final ServerPluginRepository pluginRepository; private final ServerPluginRepository pluginRepository;
private final PluginWSCommons pluginWSCommons; private final PluginWSCommons pluginWSCommons;
Expand All @@ -54,11 +59,18 @@ public InstalledAction(ServerPluginRepository pluginRepository, PluginWSCommons


@Override @Override
public void define(WebService.NewController controller) { public void define(WebService.NewController controller) {
controller.createAction("installed") WebService.NewAction action = controller.createAction("installed")
.setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name") .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name")
.setSince("5.2") .setSince("5.2")
.setHandler(this) .setHandler(this)
.setResponseExample(Resources.getResource(this.getClass(), "example-installed_plugins.json")); .setResponseExample(Resources.getResource(this.getClass(), "example-installed_plugins.json"));

action.createFieldsParam(singleton("category"))
.setDescription(format("Comma-separated list of the additional fields to be returned in response. No additional field is returned by default. Possible values are:" +
"<ul>" +
"<li>%s - category as defined in the Update Center. A connection to the Update Center is needed</li>" +
"</lu>", FIELD_CATEGORY))
.setSince("5.6");
} }


@Override @Override
Expand All @@ -69,7 +81,8 @@ public void handle(Request request, Response response) throws Exception {
jsonWriter.setSerializeEmptys(false); jsonWriter.setSerializeEmptys(false);
jsonWriter.beginObject(); jsonWriter.beginObject();


writePluginInfoList(jsonWriter, pluginInfoList); List<String> additionalFields = request.paramAsStrings(WebService.Param.FIELDS);
writePluginInfoList(jsonWriter, pluginInfoList, additionalFields == null ? Collections.<String>emptyList() : additionalFields);


jsonWriter.endObject(); jsonWriter.endObject();
jsonWriter.close(); jsonWriter.close();
Expand All @@ -79,8 +92,10 @@ private SortedSet<PluginInfo> searchPluginInfoList() {
return copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, pluginRepository.getPluginInfos()); return copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, pluginRepository.getPluginInfos());
} }


private void writePluginInfoList(JsonWriter jsonWriter, Collection<PluginInfo> pluginInfoList) { private void writePluginInfoList(JsonWriter jsonWriter, Collection<PluginInfo> pluginInfoList, List<String> additionalFields) {
ImmutableMap<String, Plugin> compatiblesPluginsByKeys = compatiblePluginsByKey(updateCenterMatrixFactory); Map<String, Plugin> compatiblesPluginsFromUpdateCenter = additionalFields.isEmpty()
pluginWSCommons.writePluginInfoList(jsonWriter, pluginInfoList, compatiblesPluginsByKeys, ARRAY_PLUGINS); ? Collections.<String, Plugin>emptyMap()
: compatiblePluginsByKey(updateCenterMatrixFactory);
pluginWSCommons.writePluginInfoList(jsonWriter, pluginInfoList, compatiblesPluginsFromUpdateCenter, ARRAY_PLUGINS);
} }
} }
Expand Up @@ -27,6 +27,7 @@
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginInfo;
import org.sonar.server.plugins.ServerPluginRepository; import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.plugins.UpdateCenterMatrixFactory; import org.sonar.server.plugins.UpdateCenterMatrixFactory;
Expand All @@ -36,9 +37,11 @@
import org.sonar.updatecenter.common.Version; import org.sonar.updatecenter.common.Version;


import static com.google.common.collect.ImmutableList.of; import static com.google.common.collect.ImmutableList.of;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS; import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static org.sonar.test.JsonAssert.assertJson; import static org.sonar.test.JsonAssert.assertJson;


Expand Down Expand Up @@ -96,10 +99,7 @@ public void empty_array_when_update_center_is_unavailable() throws Exception {
@Test @Test
public void empty_fields_are_not_serialized_to_json() throws Exception { public void empty_fields_are_not_serialized_to_json() throws Exception {
when(pluginRepository.getPluginInfos()).thenReturn( when(pluginRepository.getPluginInfos()).thenReturn(
of( of(new PluginInfo("").setName("")));
new PluginInfo("").setName("")
)
);


underTest.handle(request, response); underTest.handle(request, response);


Expand All @@ -123,14 +123,57 @@ public void verify_properties_displayed_in_json_per_plugin() throws Exception {
.setJarFile(new File(getClass().getResource(jarFilename).toURI())) .setJarFile(new File(getClass().getResource(jarFilename).toURI()))
) )
); );

underTest.handle(request, response);

verifyZeroInteractions(updateCenterMatrixFactory);
assertJson(response.outputAsString()).isSimilarTo(
"{" +
" \"plugins\":" +
" [" +
" {" +
" \"key\": \"plugKey\"," +
" \"name\": \"plugName\"," +
" \"description\": \"desc_it\"," +
" \"version\": \"1.0\"," +
" \"license\": \"license_hey\"," +
" \"organizationName\": \"org_name\"," +
" \"organizationUrl\": \"org_url\"," +
" \"homepageUrl\": \"homepage_url\"," +
" \"issueTrackerUrl\": \"issueTracker_url\"," +
" \"implementationBuild\": \"sou_rev_sha1\"" +
" }" +
" ]" +
"}"
);
}

@Test
public void category_is_returned_when_in_additional_fields() throws Exception {
String jarFilename = getClass().getSimpleName() + "/" + "some.jar";
when(pluginRepository.getPluginInfos()).thenReturn(of(
new PluginInfo("plugKey")
.setName("plugName")
.setDescription("desc_it")
.setVersion(Version.create("1.0"))
.setLicense("license_hey")
.setOrganizationName("org_name")
.setOrganizationUrl("org_url")
.setHomepageUrl("homepage_url")
.setIssueTrackerUrl("issueTracker_url")
.setImplementationBuild("sou_rev_sha1")
.setJarFile(new File(getClass().getResource(jarFilename).toURI()))
)
);
UpdateCenter updateCenter = mock(UpdateCenter.class); UpdateCenter updateCenter = mock(UpdateCenter.class);
when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter)); when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter));
when(updateCenter.findAllCompatiblePlugins()).thenReturn( when(updateCenter.findAllCompatiblePlugins()).thenReturn(
Arrays.asList( Arrays.asList(
new Plugin("plugKey") new Plugin("plugKey")
.setCategory("cat_1") .setCategory("cat_1")
) )
); );
when(request.paramAsStrings(Param.FIELDS)).thenReturn(singletonList("category"));


underTest.handle(request, response); underTest.handle(request, response);


Expand All @@ -153,7 +196,7 @@ public void verify_properties_displayed_in_json_per_plugin() throws Exception {
" }" + " }" +
" ]" + " ]" +
"}" "}"
); );
} }


@Test @Test
Expand Down
Expand Up @@ -387,7 +387,7 @@ public NewParam createFieldsParam(Collection<?> possibleValues) {
.setPossibleValues(possibleValues); .setPossibleValues(possibleValues);
} }


/**$ /**
* *
* Creates the parameter {@link org.sonar.api.server.ws.WebService.Param#TEXT_QUERY}, which is * Creates the parameter {@link org.sonar.api.server.ws.WebService.Param#TEXT_QUERY}, which is
* used to search for a subset of fields containing the supplied string. * used to search for a subset of fields containing the supplied string.
Expand Down

0 comments on commit cb09371

Please sign in to comment.