*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.updatecenter.common.Plugin;
+import static com.google.common.collect.FluentIterable.from;
+import static com.google.common.collect.ImmutableSet.copyOf;
import static com.google.common.io.Resources.getResource;
import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey;
private static final String ARRAY_INSTALLING = "installing";
private static final String ARRAY_REMOVING = "removing";
+ private static final String ARRAY_UPDATING = "updating";
private final PluginDownloader pluginDownloader;
private final ServerPluginRepository installer;
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.beginObject();
- writeInstalling(jsonWriter, compatiblePluginsByKey);
- writeRemoving(jsonWriter, compatiblePluginsByKey);
+ writePlugins(jsonWriter, compatiblePluginsByKey);
jsonWriter.endObject();
jsonWriter.close();
}
- private void writeInstalling(JsonWriter json, Map<String, Plugin> compatiblePluginsByKey) {
- Collection<PluginInfo> plugins = pluginDownloader.getDownloadedPlugins();
- pluginWSCommons.writePluginInfoList(json, plugins, compatiblePluginsByKey, ARRAY_INSTALLING);
+ private void writePlugins(JsonWriter json, Map<String, Plugin> compatiblePluginsByKey) {
+ Collection<PluginInfo> uninstalledPlugins = installer.getUninstalledPlugins();
+ Collection<PluginInfo> downloadedPlugins = pluginDownloader.getDownloadedPlugins();
+ Collection<PluginInfo> installedPlugins = installer.getPluginInfos();
+ MatchPluginKeys matchPluginKeys = new MatchPluginKeys(from(installedPlugins).transform(PluginInfoToKey.INSTANCE).toSet());
+
+ Collection<PluginInfo> newPlugins = new ArrayList<>();
+ Collection<PluginInfo> updatedPlugins = new ArrayList<>();
+ for (PluginInfo pluginInfo : downloadedPlugins) {
+ if (matchPluginKeys.apply(pluginInfo)) {
+ updatedPlugins.add(pluginInfo);
+ } else {
+ newPlugins.add(pluginInfo);
+ }
+ }
+
+ pluginWSCommons.writePluginInfoList(json, newPlugins, compatiblePluginsByKey, ARRAY_INSTALLING);
+ pluginWSCommons.writePluginInfoList(json, updatedPlugins, compatiblePluginsByKey, ARRAY_UPDATING);
+ pluginWSCommons.writePluginInfoList(json, uninstalledPlugins, compatiblePluginsByKey, ARRAY_REMOVING);
}
- private void writeRemoving(JsonWriter json, Map<String, Plugin> compatiblePluginsByKey) {
- Collection<PluginInfo> plugins = installer.getUninstalledPlugins();
- pluginWSCommons.writePluginInfoList(json, plugins, compatiblePluginsByKey, ARRAY_REMOVING);
+ private enum PluginInfoToKey implements Function<PluginInfo, String> {
+ INSTANCE;
+
+ @Override
+ public String apply(@Nonnull PluginInfo input) {
+ return input.getKey();
+ }
+ }
+
+ private static class MatchPluginKeys implements Predicate<PluginInfo> {
+ private final Set<String> pluginKeys;
+
+ private MatchPluginKeys(Collection<String> pluginKeys) {
+ this.pluginKeys = copyOf(pluginKeys);
+ }
+
+ @Override
+ public boolean apply(@Nonnull PluginInfo input) {
+ return pluginKeys.contains(input.getKey());
+ }
}
}
package org.sonar.server.plugins.ws;
import com.google.common.base.Optional;
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
import org.junit.Test;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(
"{" +
" \"installing\": []," +
- " \"removing\": []" +
+ " \"removing\": []," +
+ " \"updating\": []" +
"}"
);
}
assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(
"{" +
" \"installing\": []," +
- " \"removing\": []" +
+ " \"removing\": []," +
+ " \"updating\": []" +
"}"
);
}
@Test
public void verify_properties_displayed_in_json_per_installing_plugin() throws Exception {
- when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(gitPluginInfo()));
- UpdateCenter updateCenter = mock(UpdateCenter.class);
- when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter));
- when(updateCenter.findAllCompatiblePlugins()).thenReturn(
- Arrays.asList(
- new Plugin("scmgit")
- .setCategory("cat_1")
- )
- );
+ newUpdateCenter("scmgit");
+ when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(newScmGitPluginInfo()));
underTest.handle(request, response);
" \"implementationBuild\": \"9ce9d330c313c296fab051317cc5ad4b26319e07\"" +
" }" +
" ]," +
- " \"removing\": []" +
+ " \"removing\": []," +
+ " \"updating\": []" +
"}"
);
}
@Test
public void verify_properties_displayed_in_json_per_removing_plugin() throws Exception {
- when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(gitPluginInfo()));
+ when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(newScmGitPluginInfo()));
underTest.handle(request, response);
assertJson(response.outputAsString()).isSimilarTo(
"{" +
" \"installing\": []," +
+ " \"updating\": []," +
" \"removing\": " +
" [" +
" {" +
);
}
+ @Test
+ public void verify_properties_displayed_in_json_per_updating_plugin() throws Exception {
+ newUpdateCenter("scmgit");
+ when(serverPluginRepository.getPluginInfos()).thenReturn(of(newScmGitPluginInfo()));
+ when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(newScmGitPluginInfo()));
+
+ underTest.handle(request, response);
+
+ assertJson(response.outputAsString()).isSimilarTo(
+ "{" +
+ " \"installing\": []," +
+ " \"removing\": []," +
+ " \"updating\": " +
+ " [" +
+ " {" +
+ " \"key\": \"scmgit\"" +
+ " }" +
+ " ]" +
+ "}"
+ );
+ }
+
+ @Test
+ public void verify_properties_displayed_in_json_per_installing_removing_and_updating_plugins() throws Exception {
+ PluginInfo installed = newPluginInfo("java");
+ PluginInfo removedPlugin = newPluginInfo("js");
+ PluginInfo newPlugin = newPluginInfo("php");
+
+ newUpdateCenter("scmgit");
+ when(serverPluginRepository.getPluginInfos()).thenReturn(of(installed));
+ when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(removedPlugin));
+ when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(newPlugin, installed));
+
+ underTest.handle(request, response);
+
+ assertJson(response.outputAsString()).isSimilarTo(
+ "{" +
+ " \"installing\":" +
+ " [" +
+ " {" +
+ " \"key\": \"php\"" +
+ " }" +
+ " ]," +
+ " \"removing\":" +
+ " [" +
+ " {" +
+ " \"key\": \"js\"" +
+ " }" +
+ " ]," +
+ " \"updating\": " +
+ " [" +
+ " {" +
+ " \"key\": \"java\"" +
+ " }" +
+ " ]" +
+ "}"
+ );
+ }
+
@Test
public void installing_plugins_are_sorted_by_name_then_key_and_are_unique() throws Exception {
when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(
" \"name\": \"Foo\"," +
" }" +
" ]," +
- " \"removing\": []" +
+ " \"removing\": []," +
+ " \"updating\": []" +
"}"
);
}
assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(
"{" +
" \"installing\": []," +
+ " \"updating\": []," +
" \"removing\": " +
" [" +
" {" +
);
}
- public PluginInfo gitPluginInfo() {
+ public PluginInfo newScmGitPluginInfo() {
return new PluginInfo("scmgit")
.setName("Git")
.setDescription("Git SCM Provider.")
.setImplementationBuild("9ce9d330c313c296fab051317cc5ad4b26319e07");
}
+ public PluginInfo newPluginInfo(String key){
+ return new PluginInfo(key);
+ }
+
+ private UpdateCenter newUpdateCenter(String... pluginKeys){
+ UpdateCenter updateCenter = mock(UpdateCenter.class);
+ when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter));
+ List<Plugin> plugins = new ArrayList<>();
+ for (String pluginKey : pluginKeys) {
+ plugins.add(new Plugin(pluginKey).setCategory("cat_1"));
+ }
+ when(updateCenter.findAllCompatiblePlugins()).thenReturn(plugins);
+ return updateCenter;
+ }
+
public PluginInfo newPluginInfo(int id) {
return new PluginInfo("key" + id).setName("name" + id);
}
" ]" +
"}");
- wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{\"installing\":[],\"removing\":[]}");
+ wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{\"installing\":[],\"removing\":[],\"updating\":[]}");
// 2 - login as admin and install one plugin, update another, verify pending status in the process
userSessionRule.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
wsTester.newPostRequest("api/plugins", "update").setParam("key", "decoy").execute().assertNoContent();
wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{" +
- " \"installing\": [" +
+ " \"updating\": [" +
" {" +
" \"key\": \"decoy\"," +
" \"version\": \"1.1\"" +
" }" +
" ]," +
+ " \"installing\": []," +
" \"removing\": []" +
"}");
wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{" +
" \"installing\": [" +
" {" +
- " \"key\": \"decoy\"," +
- " \"version\": \"1.1\"" +
- " }," +
- " {" +
" \"key\": \"foo\"," +
" \"version\": \"1.0\"" +
" }" +
" ]," +
+ " \"updating\": [" +
+ " {" +
+ " \"key\": \"decoy\"," +
+ " \"version\": \"1.1\"" +
+ " }" +
+ " ]," +
" \"removing\": []" +
"}");
wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{" +
" \"installing\": []," +
+ " \"updating\": []," +
" \"removing\": [" +
" {" +
" \"key\": \"foo\"," +