aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-07-17 14:29:22 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-07-21 18:24:37 +0200
commit24d686a58de32655ab4a324b26075f6d226767a3 (patch)
tree4021f45e07acb079778dcb8b06a7592f47168c62
parent3d4701bc05805d19a695c449a93b1ef09553ba92 (diff)
downloadsonarqube-24d686a58de32655ab4a324b26075f6d226767a3.tar.gz
sonarqube-24d686a58de32655ab4a324b26075f6d226767a3.zip
SONAR-6376 ws plugins/installed and plugins/pending add category field
- use Optional when retrieving an UpdateCenter
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java21
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java37
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterMatrixFactory.java16
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java12
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java18
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java44
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java133
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java16
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java24
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java20
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java45
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java20
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java15
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java34
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java32
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java15
-rw-r--r--sonar-core/src/main/java/org/sonar/core/platform/PluginInfoFunctions.java57
23 files changed, 426 insertions, 209 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java
index 8e2edabaa89..4a77e6a6d26 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/UpgradesAction.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.platform.ws;
+import com.google.common.base.Optional;
import com.google.common.io.Resources;
import java.util.List;
import org.sonar.api.server.ws.Request;
@@ -82,18 +83,22 @@ public class UpgradesAction implements SystemWsAction {
private void writeResponse(JsonWriter jsonWriter) {
jsonWriter.beginObject();
- UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
+ Optional<UpdateCenter> updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
writeUpgrades(jsonWriter, updateCenter);
- jsonWriter.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.getDate());
+ if (updateCenter.isPresent()) {
+ jsonWriter.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.get().getDate());
+ }
jsonWriter.endObject();
}
- private void writeUpgrades(JsonWriter jsonWriter, UpdateCenter updateCenter) {
+ private void writeUpgrades(JsonWriter jsonWriter, Optional<UpdateCenter> updateCenter) {
jsonWriter.name(ARRAY_UPGRADES).beginArray();
- for (SonarUpdate sonarUpdate : updateCenter.findSonarUpdates()) {
- writeUpgrade(jsonWriter, sonarUpdate);
+ if (updateCenter.isPresent()) {
+ for (SonarUpdate sonarUpdate : updateCenter.get().findSonarUpdates()) {
+ writeUpgrade(jsonWriter, sonarUpdate);
+ }
}
jsonWriter.endArray();
@@ -132,7 +137,7 @@ public class UpgradesAction implements SystemWsAction {
for (Release release : pluginsToUpgrade) {
jsonWriter.beginObject();
- pluginWSCommons.writeMetadata(jsonWriter, (Plugin) release.getArtifact());
+ pluginWSCommons.writePlugin(jsonWriter, (Plugin) release.getArtifact());
jsonWriter.prop(PROPERTY_VERSION, release.getVersion().toString());
jsonWriter.endObject();
@@ -146,9 +151,7 @@ public class UpgradesAction implements SystemWsAction {
for (Plugin incompatiblePlugin : incompatiblePlugins) {
jsonWriter.beginObject();
-
- pluginWSCommons.writeMetadata(jsonWriter, incompatiblePlugin);
-
+ pluginWSCommons.writePlugin(jsonWriter, incompatiblePlugin);
jsonWriter.endObject();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java
index 96fec742509..a164ad7bc18 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/PluginDownloader.java
@@ -19,6 +19,14 @@
*/
package org.sonar.server.plugins;
+import com.google.common.base.Optional;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.apache.commons.io.FileUtils;
import org.picocontainer.Startable;
import org.sonar.api.utils.HttpDownloader;
@@ -28,16 +36,9 @@ import org.sonar.api.utils.log.Loggers;
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.platform.DefaultServerFileSystem;
import org.sonar.updatecenter.common.Release;
+import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
import static org.apache.commons.io.FileUtils.cleanDirectory;
@@ -120,15 +121,17 @@ public class PluginDownloader implements Startable {
}
public void download(String pluginKey, Version version) {
- for (Release release : updateCenterMatrixFactory.getUpdateCenter(true).findInstallablePlugins(pluginKey, version)) {
- try {
- downloadRelease(release);
-
- } catch (Exception e) {
- String message = String.format("Fail to download the plugin (%s, version %s) from %s (error is : %s)",
- release.getArtifact().getKey(), release.getVersion().getName(), release.getDownloadUrl(), e.getMessage());
- LOG.debug(message, e);
- throw new SonarException(message, e);
+ Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(true);
+ if (updateCenter.isPresent()) {
+ for (Release release : updateCenter.get().findInstallablePlugins(pluginKey, version)) {
+ try {
+ downloadRelease(release);
+ } catch (Exception e) {
+ String message = String.format("Fail to download the plugin (%s, version %s) from %s (error is : %s)",
+ release.getArtifact().getKey(), release.getVersion().getName(), release.getDownloadUrl(), e.getMessage());
+ LOG.debug(message, e);
+ throw new SonarException(message, e);
+ }
}
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java
index d4b3d164890..6d94cdeaa26 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterClient.java
@@ -19,6 +19,12 @@
*/
package org.sonar.server.plugins;
+import com.google.common.base.Optional;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
import org.apache.commons.io.IOUtils;
import org.sonar.api.Properties;
import org.sonar.api.Property;
@@ -30,12 +36,6 @@ import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.UpdateCenterDeserializer;
import org.sonar.updatecenter.common.UpdateCenterDeserializer.Mode;
-import java.io.InputStream;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-import java.util.Date;
-
/**
* HTTP client to load data from the remote update center hosted at http://update.sonarsource.org.
*
@@ -68,25 +68,31 @@ public class UpdateCenterClient {
private final URI uri;
private final UriReader uriReader;
+ private final boolean isActivated;
private UpdateCenter pluginCenter = null;
private long lastRefreshDate = 0;
public UpdateCenterClient(UriReader uriReader, Settings settings) throws URISyntaxException {
this.uriReader = uriReader;
this.uri = new URI(settings.getString(URL_PROPERTY));
+ this.isActivated = settings.getBoolean(ACTIVATION_PROPERTY);
Loggers.get(getClass()).info("Update center: " + uriReader.description(uri));
}
- public UpdateCenter getUpdateCenter() {
+ public Optional<UpdateCenter> getUpdateCenter() {
return getUpdateCenter(false);
}
- public UpdateCenter getUpdateCenter(boolean forceRefresh) {
+ public Optional<UpdateCenter> getUpdateCenter(boolean forceRefresh) {
+ if (!isActivated) {
+ return Optional.absent();
+ }
+
if (pluginCenter == null || forceRefresh || needsRefresh()) {
pluginCenter = init();
lastRefreshDate = System.currentTimeMillis();
}
- return pluginCenter;
+ return Optional.fromNullable(pluginCenter);
}
public Date getLastRefreshDate() {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterMatrixFactory.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterMatrixFactory.java
index b793b88cf77..6ef445f1287 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterMatrixFactory.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/UpdateCenterMatrixFactory.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins;
+import com.google.common.base.Optional;
import org.sonar.api.platform.Server;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
@@ -33,20 +34,19 @@ public class UpdateCenterMatrixFactory {
private final InstalledPluginReferentialFactory installedPluginReferentialFactory;
public UpdateCenterMatrixFactory(UpdateCenterClient centerClient, Server server,
- InstalledPluginReferentialFactory installedPluginReferentialFactory) {
+ InstalledPluginReferentialFactory installedPluginReferentialFactory) {
this.centerClient = centerClient;
this.installedPluginReferentialFactory = installedPluginReferentialFactory;
this.sonarVersion = Version.create(server.getVersion());
}
- public UpdateCenter getUpdateCenter(boolean refreshUpdateCenter) {
- UpdateCenter updatePluginCenter = centerClient.getUpdateCenter(refreshUpdateCenter);
- if (updatePluginCenter != null) {
- return updatePluginCenter.setInstalledSonarVersion(sonarVersion).registerInstalledPlugins(
+ public Optional<UpdateCenter> getUpdateCenter(boolean refreshUpdateCenter) {
+ Optional<UpdateCenter> updatePluginCenter = centerClient.getUpdateCenter(refreshUpdateCenter);
+ if (updatePluginCenter.isPresent()) {
+ return Optional.of(updatePluginCenter.get().setInstalledSonarVersion(sonarVersion).registerInstalledPlugins(
installedPluginReferentialFactory.getInstalledPluginReferential())
- .setDate(centerClient.getLastRefreshDate());
+ .setDate(centerClient.getLastRefreshDate()));
}
- return null;
+ return Optional.absent();
}
}
-
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java
index 1b4df7beccd..3ae4784eb91 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.io.Resources;
import java.util.Collection;
@@ -69,20 +70,21 @@ public class AvailableAction implements PluginsWsAction {
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.beginObject();
- UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
+ Optional<UpdateCenter> updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
writePlugins(jsonWriter, updateCenter);
-
pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter);
jsonWriter.endObject();
jsonWriter.close();
}
- private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) {
+ private void writePlugins(JsonWriter jsonWriter, Optional<UpdateCenter> updateCenter) {
jsonWriter.name(ARRAY_PLUGINS).beginArray();
- for (PluginUpdate pluginUpdate : retrieveAvailablePlugins(updateCenter)) {
- pluginWSCommons.writePluginUpdate(jsonWriter, pluginUpdate);
+ if (updateCenter.isPresent()) {
+ for (PluginUpdate pluginUpdate : retrieveAvailablePlugins(updateCenter.get())) {
+ pluginWSCommons.writePluginUpdate(jsonWriter, pluginUpdate);
+ }
}
jsonWriter.endArray();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java
index e629620df2e..32aab6c6279 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstallAction.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import javax.annotation.Nullable;
@@ -30,6 +31,7 @@ import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.user.UserSession;
import org.sonar.updatecenter.common.PluginUpdate;
+import org.sonar.updatecenter.common.UpdateCenter;
import static java.lang.String.format;
@@ -77,15 +79,21 @@ public class InstallAction implements PluginsWsAction {
}
private PluginUpdate findAvailablePluginByKey(String key) {
- PluginUpdate pluginUpdate = Iterables.find(
- updateCenterFactory.getUpdateCenter(false).findAvailablePlugins(),
- hasKey(key),
- MISSING_PLUGIN
- );
+ PluginUpdate pluginUpdate = MISSING_PLUGIN;
+
+ Optional<UpdateCenter> updateCenter = updateCenterFactory.getUpdateCenter(false);
+ if (updateCenter.isPresent()) {
+ pluginUpdate= Iterables.find(
+ updateCenter.get().findAvailablePlugins(),
+ hasKey(key),
+ MISSING_PLUGIN);
+ }
+
if (pluginUpdate == MISSING_PLUGIN) {
throw new IllegalArgumentException(
format("No plugin with key '%s' or plugin '%s' is already installed in latest version", key, key));
}
+
return pluginUpdate;
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java
index 37cc7436ec4..cf7998c71c4 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources;
import java.util.Collection;
import java.util.SortedSet;
@@ -28,9 +29,12 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.updatecenter.common.Plugin;
import static com.google.common.collect.ImmutableSortedSet.copyOf;
import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR;
+import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey;
/**
* Implementation of the {@code installed} action for the Plugins WebService.
@@ -40,10 +44,12 @@ public class InstalledAction implements PluginsWsAction {
private final ServerPluginRepository pluginRepository;
private final PluginWSCommons pluginWSCommons;
+ private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
- public InstalledAction(ServerPluginRepository pluginRepository, PluginWSCommons pluginWSCommons) {
+ public InstalledAction(ServerPluginRepository pluginRepository, PluginWSCommons pluginWSCommons, UpdateCenterMatrixFactory updateCenterMatrixFactory) {
this.pluginRepository = pluginRepository;
this.pluginWSCommons = pluginWSCommons;
+ this.updateCenterMatrixFactory = updateCenterMatrixFactory;
}
@Override
@@ -57,28 +63,24 @@ public class InstalledAction implements PluginsWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
- Collection<PluginInfo> infos = retrieveAndSortPluginMetadata();
+ Collection<PluginInfo> pluginInfoList = searchPluginInfoList();
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.setSerializeEmptys(false);
jsonWriter.beginObject();
- writeMetadataList(jsonWriter, infos);
+ writePluginInfoList(jsonWriter, pluginInfoList);
jsonWriter.endObject();
jsonWriter.close();
}
- private SortedSet<PluginInfo> retrieveAndSortPluginMetadata() {
+ private SortedSet<PluginInfo> searchPluginInfoList() {
return copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, pluginRepository.getPluginInfos());
}
- private void writeMetadataList(JsonWriter jsonWriter, Collection<PluginInfo> pluginMetadatas) {
- jsonWriter.name(ARRAY_PLUGINS);
- jsonWriter.beginArray();
- for (PluginInfo pluginMetadata : pluginMetadatas) {
- pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata);
- }
- jsonWriter.endArray();
+ private void writePluginInfoList(JsonWriter jsonWriter, Collection<PluginInfo> pluginInfoList) {
+ ImmutableMap<String, Plugin> compatiblesPluginsByKeys = compatiblePluginsByKey(updateCenterMatrixFactory);
+ pluginWSCommons.writePluginInfoList(jsonWriter, pluginInfoList, compatiblesPluginsByKeys, ARRAY_PLUGINS);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java
index 86293e731d5..c7ea6d33a29 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java
@@ -19,6 +19,9 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collection;
+import java.util.Map;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -26,12 +29,11 @@ import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.updatecenter.common.Plugin;
-import java.util.Collection;
-
-import static com.google.common.collect.ImmutableSortedSet.copyOf;
import static com.google.common.io.Resources.getResource;
-import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR;
+import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey;
/**
* Implementation of the {@code pending} action for the Plugins WebService.
@@ -44,13 +46,15 @@ public class PendingAction implements PluginsWsAction {
private final PluginDownloader pluginDownloader;
private final ServerPluginRepository installer;
private final PluginWSCommons pluginWSCommons;
+ private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
public PendingAction(PluginDownloader pluginDownloader,
- ServerPluginRepository installer,
- PluginWSCommons pluginWSCommons) {
+ ServerPluginRepository installer,
+ PluginWSCommons pluginWSCommons, UpdateCenterMatrixFactory updateCenterMatrixFactory) {
this.pluginDownloader = pluginDownloader;
this.installer = installer;
this.pluginWSCommons = pluginWSCommons;
+ this.updateCenterMatrixFactory = updateCenterMatrixFactory;
}
@Override
@@ -64,36 +68,24 @@ public class PendingAction implements PluginsWsAction {
@Override
public void handle(Request request, Response response) throws Exception {
+ ImmutableMap<String, Plugin> compatiblePluginsByKey = compatiblePluginsByKey(updateCenterMatrixFactory);
+
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.beginObject();
-
- writeInstalling(jsonWriter);
-
- writeRemoving(jsonWriter);
-
+ writeInstalling(jsonWriter, compatiblePluginsByKey);
+ writeRemoving(jsonWriter, compatiblePluginsByKey);
jsonWriter.endObject();
jsonWriter.close();
}
- private void writeInstalling(JsonWriter jsonWriter) {
- jsonWriter.name(ARRAY_INSTALLING);
- jsonWriter.beginArray();
+ private void writeInstalling(JsonWriter json, Map<String, Plugin> compatiblePluginsByKey) {
Collection<PluginInfo> plugins = pluginDownloader.getDownloadedPlugins();
- for (PluginInfo pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) {
- pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata);
- }
- jsonWriter.endArray();
+ pluginWSCommons.writePluginInfoList(json, plugins, compatiblePluginsByKey, ARRAY_INSTALLING);
}
- private void writeRemoving(JsonWriter jsonWriter) {
- jsonWriter.name(ARRAY_REMOVING);
- jsonWriter.beginArray();
+ private void writeRemoving(JsonWriter json, Map<String, Plugin> compatiblePluginsByKey) {
Collection<PluginInfo> plugins = installer.getUninstalledPlugins();
- for (PluginInfo pluginMetadata : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) {
- pluginWSCommons.writePluginMetadata(jsonWriter, pluginMetadata);
- }
- jsonWriter.endArray();
+ pluginWSCommons.writePluginInfoList(json, plugins, compatiblePluginsByKey, ARRAY_REMOVING);
}
-
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java
index 6c764861e38..209df136186 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PluginWSCommons.java
@@ -21,11 +21,19 @@ package org.sonar.server.plugins.ws;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
+import java.util.Collections;
import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.core.platform.PluginInfo;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.updatecenter.common.Artifact;
import org.sonar.updatecenter.common.Plugin;
import org.sonar.updatecenter.common.PluginUpdate;
@@ -33,9 +41,12 @@ import org.sonar.updatecenter.common.Release;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
+import static com.google.common.collect.ImmutableSortedSet.copyOf;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import static java.lang.String.CASE_INSENSITIVE_ORDER;
+import static org.sonar.core.platform.PluginInfoFunctions.toKey;
+import static org.sonar.core.platform.PluginInfoFunctions.toName;
public class PluginWSCommons {
static final String PROPERTY_KEY = "key";
@@ -61,54 +72,48 @@ public class PluginWSCommons {
static final String PROPERTY_CHANGE_LOG_URL = "changeLogUrl";
public static final Ordering<PluginInfo> NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural()
- .onResultOf(PluginMetadataToName.INSTANCE)
- .compound(Ordering.natural().onResultOf(PluginMetadataToKey.INSTANCE));
+ .onResultOf(toName())
+ .compound(Ordering.natural().onResultOf(toKey()));
public static final Comparator<Plugin> NAME_KEY_PLUGIN_ORDERING = Ordering.from(CASE_INSENSITIVE_ORDER)
.onResultOf(PluginToName.INSTANCE)
.compound(
- Ordering.from(CASE_INSENSITIVE_ORDER).onResultOf(PluginToKey.INSTANCE)
+ Ordering.from(CASE_INSENSITIVE_ORDER).onResultOf(PluginToKeyFunction.INSTANCE)
);
public static final Comparator<PluginUpdate> NAME_KEY_PLUGIN_UPDATE_ORDERING = Ordering.from(NAME_KEY_PLUGIN_ORDERING)
.onResultOf(PluginUpdateToPlugin.INSTANCE);
- public void writePluginMetadata(JsonWriter jsonWriter, PluginInfo info) {
- jsonWriter.beginObject();
+ void writePluginInfo(JsonWriter json, PluginInfo pluginInfo, @Nullable String category) {
+ json.beginObject();
- writeMetadata(jsonWriter, info);
-
- jsonWriter.endObject();
- }
-
- public void writeMetadata(JsonWriter jsonWriter, PluginInfo pluginMetadata) {
- jsonWriter.prop(PROPERTY_KEY, pluginMetadata.getKey());
- jsonWriter.prop(PROPERTY_NAME, pluginMetadata.getName());
- jsonWriter.prop(PROPERTY_DESCRIPTION, pluginMetadata.getDescription());
- Version version = pluginMetadata.getVersion();
+ json.prop(PROPERTY_KEY, pluginInfo.getKey());
+ json.prop(PROPERTY_NAME, pluginInfo.getName());
+ json.prop(PROPERTY_DESCRIPTION, pluginInfo.getDescription());
+ Version version = pluginInfo.getVersion();
if (version != null) {
- jsonWriter.prop(PROPERTY_VERSION, version.getName());
+ json.prop(PROPERTY_VERSION, version.getName());
}
- jsonWriter.prop(PROPERTY_LICENSE, pluginMetadata.getLicense());
- jsonWriter.prop(PROPERTY_ORGANIZATION_NAME, pluginMetadata.getOrganizationName());
- jsonWriter.prop(PROPERTY_ORGANIZATION_URL, pluginMetadata.getOrganizationUrl());
- jsonWriter.prop(PROPERTY_HOMEPAGE_URL, pluginMetadata.getHomepageUrl());
- jsonWriter.prop(PROPERTY_ISSUE_TRACKER_URL, pluginMetadata.getIssueTrackerUrl());
- jsonWriter.prop(PROPERTY_IMPLEMENTATION_BUILD, pluginMetadata.getImplementationBuild());
+ json.prop(PROPERTY_CATEGORY, category);
+ json.prop(PROPERTY_LICENSE, pluginInfo.getLicense());
+ json.prop(PROPERTY_ORGANIZATION_NAME, pluginInfo.getOrganizationName());
+ json.prop(PROPERTY_ORGANIZATION_URL, pluginInfo.getOrganizationUrl());
+ json.prop(PROPERTY_HOMEPAGE_URL, pluginInfo.getHomepageUrl());
+ json.prop(PROPERTY_ISSUE_TRACKER_URL, pluginInfo.getIssueTrackerUrl());
+ json.prop(PROPERTY_IMPLEMENTATION_BUILD, pluginInfo.getImplementationBuild());
+
+ json.endObject();
}
- public void writePluginUpdate(JsonWriter jsonWriter, PluginUpdate pluginUpdate) {
- jsonWriter.beginObject();
- Plugin plugin = pluginUpdate.getPlugin();
-
- writeMetadata(jsonWriter, plugin);
-
- writeRelease(jsonWriter, pluginUpdate.getRelease());
-
- writeUpdate(jsonWriter, pluginUpdate);
-
- jsonWriter.endObject();
+ public void writePluginInfoList(JsonWriter json, Iterable<PluginInfo> plugins, Map<String, Plugin> compatiblePluginsByKey, String propertyName) {
+ json.name(propertyName);
+ json.beginArray();
+ for (PluginInfo pluginInfo : copyOf(NAME_KEY_PLUGIN_METADATA_COMPARATOR, plugins)) {
+ Plugin plugin = compatiblePluginsByKey.get(pluginInfo.getKey());
+ writePluginInfo(json, pluginInfo, categoryOrNull(plugin));
+ }
+ json.endArray();
}
- public void writeMetadata(JsonWriter jsonWriter, Plugin plugin) {
+ public void writePlugin(JsonWriter jsonWriter, Plugin plugin) {
jsonWriter.prop(PROPERTY_KEY, plugin.getKey());
jsonWriter.prop(PROPERTY_NAME, plugin.getName());
jsonWriter.prop(PROPERTY_CATEGORY, plugin.getCategory());
@@ -121,6 +126,16 @@ public class PluginWSCommons {
jsonWriter.prop(PROPERTY_ISSUE_TRACKER_URL, plugin.getIssueTrackerUrl());
}
+ public void writePluginUpdate(JsonWriter json, PluginUpdate pluginUpdate) {
+ Plugin plugin = pluginUpdate.getPlugin();
+
+ json.beginObject();
+ writePlugin(json, plugin);
+ writeRelease(json, pluginUpdate.getRelease());
+ writeUpdate(json, pluginUpdate);
+ json.endObject();
+ }
+
public void writeRelease(JsonWriter jsonWriter, Release release) {
jsonWriter.name(OBJECT_RELEASE).beginObject();
@@ -214,61 +229,57 @@ public class PluginWSCommons {
* "updateCenterRefresh": "2015-04-24T16:08:36+0200"
* </pre>
*/
- public void writeUpdateCenterProperties(JsonWriter jsonWriter, UpdateCenter updateCenter) {
- jsonWriter.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.getDate());
- }
-
- private enum ReleaseToArtifact implements Function<Release, Artifact> {
- INSTANCE;
-
- @Override
- public Artifact apply(@Nonnull Release input) {
- return input.getArtifact();
+ public void writeUpdateCenterProperties(JsonWriter json, Optional<UpdateCenter> updateCenter) {
+ if (updateCenter.isPresent()) {
+ json.propDateTime(PROPERTY_UPDATE_CENTER_REFRESH, updateCenter.get().getDate());
}
}
- private enum PluginMetadataToName implements Function<PluginInfo, String> {
+ enum PluginToKeyFunction implements Function<Plugin, String> {
INSTANCE;
@Override
- public String apply(@Nonnull PluginInfo input) {
- return input.getName();
+ public String apply(@Nonnull Plugin input) {
+ return input.getKey();
}
}
- private enum PluginMetadataToKey implements Function<PluginInfo, String> {
+ private enum ReleaseToArtifact implements Function<Release, Artifact> {
INSTANCE;
-
@Override
- public String apply(@Nonnull PluginInfo input) {
- return input.getKey();
+ public Artifact apply(@Nonnull Release input) {
+ return input.getArtifact();
}
+
}
private enum PluginUpdateToPlugin implements Function<PluginUpdate, Plugin> {
INSTANCE;
-
@Override
public Plugin apply(@Nonnull PluginUpdate input) {
return input.getPlugin();
}
}
- private enum PluginToKey implements Function<Plugin, String> {
+ private enum PluginToName implements Function<Plugin, String> {
INSTANCE;
-
@Override
public String apply(@Nonnull Plugin input) {
- return input.getKey();
+ return input.getName();
}
}
- private enum PluginToName implements Function<Plugin, String> {
- INSTANCE;
+ static String categoryOrNull(Plugin plugin) {
+ return plugin != null ? plugin.getCategory() : null;
+ }
- @Override
- public String apply(@Nonnull Plugin input) {
- return input.getName();
- }
+ private static List<Plugin> compatiblePlugins(UpdateCenterMatrixFactory updateCenterMatrixFactory) {
+ Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(false);
+ return updateCenter.isPresent() ? updateCenter.get().findAllCompatiblePlugins() : Collections.<Plugin>emptyList();
+ }
+
+ static ImmutableMap<String, Plugin> compatiblePluginsByKey(UpdateCenterMatrixFactory updateCenterMatrixFactory) {
+ List<Plugin> compatiblePlugins = compatiblePlugins(updateCenterMatrixFactory);
+ return Maps.uniqueIndex(compatiblePlugins, PluginToKeyFunction.INSTANCE);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java
index 1a8a3bc78e5..24473e9ed95 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdateAction.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import org.sonar.api.server.ws.Request;
@@ -32,6 +33,7 @@ import org.sonar.updatecenter.common.PluginUpdate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.sonar.updatecenter.common.UpdateCenter;
import static java.lang.String.format;
@@ -80,11 +82,17 @@ public class UpdateAction implements PluginsWsAction {
@Nonnull
private PluginUpdate findPluginUpdateByKey(String key) {
- PluginUpdate pluginUpdate = Iterables.find(
- updateCenterFactory.getUpdateCenter(false).findPluginUpdates(),
- new PluginKeyPredicate(key),
- MISSING_PLUGIN
+ Optional<UpdateCenter> updateCenter = updateCenterFactory.getUpdateCenter(false);
+ PluginUpdate pluginUpdate = MISSING_PLUGIN;
+
+ if (updateCenter.isPresent()) {
+ pluginUpdate = Iterables.find(
+ updateCenter.get().findPluginUpdates(),
+ new PluginKeyPredicate(key),
+ MISSING_PLUGIN
);
+ }
+
if (pluginUpdate == MISSING_PLUGIN) {
throw new IllegalArgumentException(
format("No plugin with key '%s' or plugin '%s' is already in latest compatible version", key, key));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java
index 1e6014366bd..430d60cdfd9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java
@@ -20,9 +20,13 @@
package org.sonar.server.plugins.ws;
import com.google.common.base.Function;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Ordering;
import com.google.common.io.Resources;
+import java.util.Collection;
+import java.util.List;
+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;
@@ -33,10 +37,6 @@ import org.sonar.updatecenter.common.Plugin;
import org.sonar.updatecenter.common.PluginUpdate;
import org.sonar.updatecenter.common.UpdateCenter;
-import javax.annotation.Nonnull;
-import java.util.Collection;
-import java.util.List;
-
/**
* Implementation of the {@code updates} action for the Plugins WebService.
*/
@@ -60,8 +60,8 @@ public class UpdatesAction implements PluginsWsAction {
private final PluginUpdateAggregator aggregator;
public UpdatesAction(UpdateCenterMatrixFactory updateCenterMatrixFactory,
- PluginWSCommons pluginWSCommons,
- PluginUpdateAggregator aggregator) {
+ PluginWSCommons pluginWSCommons,
+ PluginUpdateAggregator aggregator) {
this.updateCenterMatrixFactory = updateCenterMatrixFactory;
this.pluginWSCommons = pluginWSCommons;
this.aggregator = aggregator;
@@ -87,7 +87,7 @@ public class UpdatesAction implements PluginsWsAction {
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.beginObject();
- UpdateCenter updateCenter = updateCenterMatrixFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
+ Optional<UpdateCenter> updateCenter = updateCenterMatrixFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
writePlugins(jsonWriter, updateCenter);
@@ -97,11 +97,13 @@ public class UpdatesAction implements PluginsWsAction {
jsonWriter.close();
}
- private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) {
+ private void writePlugins(JsonWriter jsonWriter, Optional<UpdateCenter> updateCenter) {
jsonWriter.name(ARRAY_PLUGINS);
jsonWriter.beginArray();
- for (PluginUpdateAggregate aggregate : retrieveUpdatablePlugins(updateCenter)) {
- writePluginUpdateAggregate(jsonWriter, aggregate);
+ if (updateCenter.isPresent()) {
+ for (PluginUpdateAggregate aggregate : retrieveUpdatablePlugins(updateCenter.get())) {
+ writePluginUpdateAggregate(jsonWriter, aggregate);
+ }
}
jsonWriter.endArray();
}
@@ -110,7 +112,7 @@ public class UpdatesAction implements PluginsWsAction {
jsonWriter.beginObject();
Plugin plugin = aggregate.getPlugin();
- pluginWSCommons.writeMetadata(jsonWriter, plugin);
+ pluginWSCommons.writePlugin(jsonWriter, plugin);
writeUpdates(jsonWriter, aggregate.getUpdates());
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
index 404a93a8c16..cbc4aeee1a3 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java
@@ -162,7 +162,7 @@ public final class JRubyFacade {
}
public UpdateCenter getUpdatePluginCenter(boolean forceReload) {
- return get(UpdateCenterMatrixFactory.class).getUpdateCenter(forceReload);
+ return get(UpdateCenterMatrixFactory.class).getUpdateCenter(forceReload).orNull();
}
public PluginReferential getInstalledPluginReferential() {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java
index 305fdab3cdd..0f9f96525c9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/UpgradesActionTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.platform.ws;
+import com.google.common.base.Optional;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.server.ws.Request;
@@ -57,7 +58,7 @@ public class UpgradesActionTest {
@Before
public void wireMocks() {
- when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter);
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
when(updateCenter.getDate()).thenReturn(DateUtils.parseDateTime("2015-04-24T16:08:36+0200"));
}
@@ -88,6 +89,15 @@ public class UpgradesActionTest {
}
@Test
+ public void empty_array_is_returned_when_update_center_is_unavailable() throws Exception {
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.<UpdateCenter>absent());
+
+ underTest.handle(request, response);
+
+ assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_UPGRADE_LIST);
+ }
+
+ @Test
public void verify_JSON_response_against_example() throws Exception {
SonarUpdate sonarUpdate = createSonar_51_update();
when(updateCenter.findSonarUpdates()).thenReturn(of(sonarUpdate));
@@ -126,7 +136,7 @@ public class UpgradesActionTest {
.setDescription("New overall layout, merge Issues Drilldown [...]")
.setDownloadUrl("http://dist.sonar.codehaus.org/sonarqube-5.1.zip")
.setChangelogUrl("http://jira.sonarsource.com/secure/ReleaseNote.jspa?projectId=11694&version=20666")
- );
+ );
sonarUpdate.addIncompatiblePlugin(brandingPlugin);
sonarUpdate.addPluginToUpgrade(new Release(viewsPlugin, Version.create("2.8")));
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java
index 802e6f011b1..7f78fc6c538 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/PluginDownloaderTest.java
@@ -19,6 +19,9 @@
*/
package org.sonar.server.plugins;
+import com.google.common.base.Optional;
+import java.io.File;
+import java.net.URI;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@@ -36,9 +39,6 @@ import org.sonar.updatecenter.common.Release;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
-import java.io.File;
-import java.net.URI;
-
import static com.google.common.collect.Lists.newArrayList;
import static org.apache.commons.io.FileUtils.copyFileToDirectory;
import static org.apache.commons.io.FileUtils.touch;
@@ -70,7 +70,7 @@ public class PluginDownloaderTest {
public void before() throws Exception {
updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class);
updateCenter = mock(UpdateCenter.class);
- when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter);
+ when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
httpDownloader = mock(HttpDownloader.class);
doAnswer(new Answer() {
@@ -124,6 +124,18 @@ public class PluginDownloaderTest {
assertThat(new File(downloadDir, "test-1.0.jar.tmp")).doesNotExist();
}
+ @Test
+ public void download_when_update_center_is_unavailable_with_no_exception_thrown() {
+ when(updateCenterMatrixFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.<UpdateCenter>absent());
+
+ Plugin test = new Plugin("test");
+ Release test10 = new Release(test, "1.0").setDownloadUrl("http://server/test-1.0.jar");
+ test.addRelease(test10);
+
+ pluginDownloader.start();
+ pluginDownloader.download("foo", create("1.0"));
+ }
+
/**
* SONAR-4685
*/
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java
index 9d6581bb583..b6d1e32e869 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/UpdateCenterClientTest.java
@@ -19,6 +19,9 @@
*/
package org.sonar.server.plugins;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.Settings;
@@ -27,11 +30,8 @@ import org.sonar.api.utils.UriReader;
import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.charset.StandardCharsets;
-
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.guava.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
@@ -41,43 +41,47 @@ import static org.mockito.Mockito.when;
public class UpdateCenterClientTest {
- private static final String BASE_URL = "http://update.sonarsource.org";
- private UpdateCenterClient client;
- private UriReader reader;
+ static final String BASE_URL = "http://update.sonarsource.org";
+ UriReader reader;
+ Settings settings;
+
+ UpdateCenterClient underTest;
@Before
public void startServer() throws Exception {
reader = mock(UriReader.class);
- Settings settings = new Settings().setProperty(UpdateCenterClient.URL_PROPERTY, BASE_URL);
- client = new UpdateCenterClient(reader, settings);
+ settings = new Settings()
+ .setProperty(UpdateCenterClient.URL_PROPERTY, BASE_URL)
+ .setProperty(UpdateCenterClient.ACTIVATION_PROPERTY, true);
+ underTest = new UpdateCenterClient(reader, settings);
}
@Test
public void downloadUpdateCenter() throws URISyntaxException {
when(reader.readString(new URI(BASE_URL), StandardCharsets.UTF_8)).thenReturn("publicVersions=2.2,2.3");
- UpdateCenter plugins = client.getUpdateCenter();
+ UpdateCenter plugins = underTest.getUpdateCenter().get();
verify(reader, times(1)).readString(new URI(BASE_URL), StandardCharsets.UTF_8);
assertThat(plugins.getSonar().getVersions()).containsOnly(Version.create("2.2"), Version.create("2.3"));
- assertThat(client.getLastRefreshDate()).isNotNull();
+ assertThat(underTest.getLastRefreshDate()).isNotNull();
}
@Test
public void not_available_before_initialization() {
- assertThat(client.getLastRefreshDate()).isNull();
+ assertThat(underTest.getLastRefreshDate()).isNull();
}
@Test
public void ignore_connection_errors() {
when(reader.readString(any(URI.class), eq(StandardCharsets.UTF_8))).thenThrow(new SonarException());
- assertThat(client.getUpdateCenter()).isNull();
+ assertThat(underTest.getUpdateCenter()).isAbsent();
}
@Test
public void cache_data() throws Exception {
when(reader.readString(new URI(BASE_URL), StandardCharsets.UTF_8)).thenReturn("sonar.versions=2.2,2.3");
- client.getUpdateCenter();
- client.getUpdateCenter();
+ underTest.getUpdateCenter();
+ underTest.getUpdateCenter();
verify(reader, times(1)).readString(new URI(BASE_URL), StandardCharsets.UTF_8);
}
@@ -86,9 +90,16 @@ public class UpdateCenterClientTest {
public void forceRefresh() throws Exception {
when(reader.readString(new URI(BASE_URL), StandardCharsets.UTF_8)).thenReturn("sonar.versions=2.2,2.3");
- client.getUpdateCenter();
- client.getUpdateCenter(true);
+ underTest.getUpdateCenter();
+ underTest.getUpdateCenter(true);
verify(reader, times(2)).readString(new URI(BASE_URL), StandardCharsets.UTF_8);
}
+
+ @Test
+ public void update_center_is_null_when_property_is_false() {
+ settings.setProperty(UpdateCenterClient.ACTIVATION_PROPERTY, false);
+
+ assertThat(underTest.getUpdateCenter()).isAbsent();
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java
index 8d28df8418a..6bb398cfadc 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AbstractUpdateCenterBasedPluginsWsActionTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import org.junit.Before;
import org.sonar.api.server.ws.Request;
import org.sonar.api.utils.DateUtils;
@@ -74,7 +75,7 @@ public abstract class AbstractUpdateCenterBasedPluginsWsActionTest {
@Before
public void wireMocksTogether() {
- when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter);
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
when(updateCenter.getDate()).thenReturn(DateUtils.parseDateTime("2015-04-24T16:08:36+0200"));
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java
index 205c657fa45..2524a4962ce 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import org.junit.Test;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.DateUtils;
@@ -26,9 +27,11 @@ import org.sonar.server.ws.WsTester;
import org.sonar.updatecenter.common.Plugin;
import org.sonar.updatecenter.common.PluginUpdate;
import org.sonar.updatecenter.common.Release;
+import org.sonar.updatecenter.common.UpdateCenter;
import static com.google.common.collect.ImmutableList.of;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.when;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE;
@@ -81,10 +84,19 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
}
@Test
+ public void empty_array_is_returned_when_update_center_is_not_accessible() throws Exception {
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.<UpdateCenter>absent());
+
+ underTest.handle(request, response);
+
+ assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST);
+ }
+
+ @Test
public void verify_properties_displayed_in_json_per_plugin() throws Exception {
when(updateCenter.findAvailablePlugins()).thenReturn(of(
pluginUpdate(FULL_PROPERTIES_PLUGIN_RELEASE, COMPATIBLE)
- ));
+ ));
underTest.handle(request, response);
@@ -114,7 +126,7 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
private void checkStatusDisplayedInJson(PluginUpdate.Status status, String expectedValue) throws Exception {
when(updateCenter.findAvailablePlugins()).thenReturn(of(
pluginUpdate(release(PLUGIN_1, "1.0.0"), status)
- ));
+ ));
underTest.handle(request, response);
@@ -128,7 +140,7 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
" }" +
" ]" +
"}"
- );
+ );
}
@Test
@@ -139,6 +151,6 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
pluginUpdate("key2", "name2"),
pluginUpdate("key0", "name0"),
pluginUpdate("key1", "name1")
- ));
+ ));
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java
index 6cac3de746d..fd4d2cd478f 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstallActionTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Rule;
@@ -49,7 +50,7 @@ public class InstallActionTest {
private static final String ACTION_KEY = "install";
private static final String KEY_PARAM = "key";
private static final String PLUGIN_KEY = "pluginKey";
-
+
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
@@ -68,7 +69,7 @@ public class InstallActionTest {
@Before
public void wireMocks() {
- when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter);
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
}
@@ -124,6 +125,16 @@ public class InstallActionTest {
}
@Test
+ public void IAE_is_raised_when_update_center_is_unavailable() throws Exception {
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.<UpdateCenter>absent());
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("No plugin with key 'pluginKey'");
+
+ validRequest.execute();
+ }
+
+ @Test
public void if_plugin_is_found_available_download_is_triggered_with_latest_version_from_updatecenter() throws Exception {
Version version = Version.create("1.0");
when(updateCenter.findAvailablePlugins()).thenReturn(ImmutableList.of(
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java
index 2087259a96e..6e0ba04f45c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java
@@ -19,7 +19,9 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import java.io.File;
+import java.util.Arrays;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -27,11 +29,15 @@ import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.ws.WsTester;
+import org.sonar.updatecenter.common.Plugin;
+import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
import static com.google.common.collect.ImmutableList.of;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.test.JsonAssert.assertJson;
@@ -46,11 +52,13 @@ public class InstalledActionTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
- private ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class);
- private InstalledAction underTest = new InstalledAction(pluginRepository, new PluginWSCommons());
+ ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class);
+ UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class, RETURNS_DEEP_STUBS);
- private Request request = mock(Request.class);
- private WsTester.TestResponse response = new WsTester.TestResponse();
+ InstalledAction underTest = new InstalledAction(pluginRepository, new PluginWSCommons(), updateCenterMatrixFactory);
+
+ Request request = mock(Request.class);
+ WsTester.TestResponse response = new WsTester.TestResponse();
@Test
public void action_installed_is_defined() {
@@ -77,6 +85,15 @@ public class InstalledActionTest {
}
@Test
+ public void empty_array_when_update_center_is_unavailable() throws Exception {
+ when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.<UpdateCenter>absent());
+
+ underTest.handle(request, response);
+
+ assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(JSON_EMPTY_PLUGIN_LIST);
+ }
+
+ @Test
public void empty_fields_are_not_serialized_to_json() throws Exception {
when(pluginRepository.getPluginInfos()).thenReturn(
of(
@@ -106,6 +123,14 @@ public class InstalledActionTest {
.setJarFile(new File(getClass().getResource(jarFilename).toURI()))
)
);
+ UpdateCenter updateCenter = mock(UpdateCenter.class);
+ when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter));
+ when(updateCenter.findAllCompatiblePlugins()).thenReturn(
+ Arrays.asList(
+ new Plugin("plugKey")
+ .setCategory("cat_1")
+ )
+ );
underTest.handle(request, response);
@@ -118,6 +143,7 @@ public class InstalledActionTest {
" \"name\": \"plugName\"," +
" \"description\": \"desc_it\"," +
" \"version\": \"1.0\"," +
+ " \"category\":\"cat_1\"," +
" \"license\": \"license_hey\"," +
" \"organizationName\": \"org_name\"," +
" \"organizationUrl\": \"org_url\"," +
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java
index 143747095e8..b35c4c31c1a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java
@@ -19,17 +19,23 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
+import java.util.Arrays;
import org.junit.Test;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
import org.sonar.core.platform.PluginInfo;
import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.ws.WsTester;
+import org.sonar.updatecenter.common.Plugin;
+import org.sonar.updatecenter.common.UpdateCenter;
import org.sonar.updatecenter.common.Version;
import static com.google.common.collect.ImmutableList.of;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.test.JsonAssert.assertJson;
@@ -40,7 +46,8 @@ public class PendingActionTest {
PluginDownloader pluginDownloader = mock(PluginDownloader.class);
ServerPluginRepository serverPluginRepository = mock(ServerPluginRepository.class);
- PendingAction underTest = new PendingAction(pluginDownloader, serverPluginRepository, new PluginWSCommons());
+ UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class, RETURNS_DEEP_STUBS);
+ PendingAction underTest = new PendingAction(pluginDownloader, serverPluginRepository, new PluginWSCommons(), updateCenterMatrixFactory);
Request request = mock(Request.class);
WsTester.TestResponse response = new WsTester.TestResponse();
@@ -74,8 +81,30 @@ public class PendingActionTest {
}
@Test
+ public void empty_arrays_are_returned_when_update_center_is_unavailable() throws Exception {
+ when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.<UpdateCenter>absent());
+
+ underTest.handle(request, response);
+
+ assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo(
+ "{" +
+ " \"installing\": []," +
+ " \"removing\": []" +
+ "}"
+ );
+ }
+
+ @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")
+ )
+ );
underTest.handle(request, response);
@@ -89,6 +118,7 @@ public class PendingActionTest {
" \"description\": \"Git SCM Provider.\"," +
" \"version\": \"1.0\"," +
" \"license\": \"GNU LGPL 3\"," +
+ " \"category\":\"cat_1\"," +
" \"organizationName\": \"SonarSource\"," +
" \"organizationUrl\": \"http://www.sonarsource.com\"," +
" \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," +
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java
index 11403c59936..146115b6a4b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginWSCommonsTest.java
@@ -45,7 +45,7 @@ public class PluginWSCommonsTest {
@Test
public void verify_properties_written_by_writePluginMetadata() {
- underTest.writePluginMetadata(jsonWriter, gitPluginInfo());
+ underTest.writePluginInfo(jsonWriter, gitPluginInfo(), null);
jsonWriter.close();
assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{" +
@@ -63,9 +63,7 @@ public class PluginWSCommonsTest {
@Test
public void verify_properties_written_by_writeMetadata() {
- jsonWriter.beginObject();
- underTest.writeMetadata(jsonWriter, gitPluginInfo());
- jsonWriter.endObject();
+ underTest.writePluginInfo(jsonWriter, gitPluginInfo(), "cat_1");
jsonWriter.close();
assertJson(response.outputAsString()).setStrictArrayOrder(true).isSimilarTo("{" +
@@ -74,6 +72,7 @@ public class PluginWSCommonsTest {
" \"description\": \"Git SCM Provider.\"," +
" \"version\": \"1.0\"," +
" \"license\": \"GNU LGPL 3\"," +
+ " \"category\":\"cat_1\"" +
" \"organizationName\": \"SonarSource\"," +
" \"organizationUrl\": \"http://www.sonarsource.com\"," +
" \"homepageUrl\": \"http://redirect.sonarsource.com/plugins/scmgit.html\"," +
@@ -105,7 +104,7 @@ public class PluginWSCommonsTest {
@Test
public void verify_properties_written_by_writeMetadata_from_plugin() {
jsonWriter.beginObject();
- underTest.writeMetadata(jsonWriter, newPlugin());
+ underTest.writePlugin(jsonWriter, newPlugin());
jsonWriter.endObject();
jsonWriter.close();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java
index 22c8ac0fc05..4f840c72b49 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdateActionTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins.ws;
+import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Rule;
@@ -70,7 +71,7 @@ public class UpdateActionTest {
@Before
public void setUp() {
- when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter);
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
userSessionRule.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
}
@@ -126,11 +127,21 @@ public class UpdateActionTest {
}
@Test
+ public void IAE_is_raised_when_update_center_is_unavailable() throws Exception {
+ when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.<UpdateCenter>absent());
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("No plugin with key 'pluginKey'");
+
+ underTest.handle(validRequest, response);
+ }
+
+ @Test
public void if_plugin_has_an_update_download_is_triggered_with_latest_version_from_updatecenter() throws Exception {
Version version = Version.create("1.0");
when(updateCenter.findPluginUpdates()).thenReturn(ImmutableList.of(
PluginUpdate.createWithStatus(new Release(new Plugin(PLUGIN_KEY), version), Status.COMPATIBLE)
- ));
+ ));
underTest.handle(validRequest, response);
diff --git a/sonar-core/src/main/java/org/sonar/core/platform/PluginInfoFunctions.java b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfoFunctions.java
new file mode 100644
index 00000000000..c0aaea96e83
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/platform/PluginInfoFunctions.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.core.platform;
+
+import com.google.common.base.Function;
+import javax.annotation.Nonnull;
+
+public final class PluginInfoFunctions {
+
+ private PluginInfoFunctions() {
+ // utility class
+ }
+
+ public static Function<PluginInfo, String> toName() {
+ return PluginInfoToName.INSTANCE;
+ }
+
+ public static Function<PluginInfo, String> toKey() {
+ return PluginInfoToKey.INSTANCE;
+ }
+
+ private enum PluginInfoToName implements Function<PluginInfo, String> {
+ INSTANCE;
+
+ @Override
+ public String apply(@Nonnull PluginInfo input) {
+ return input.getName();
+ }
+ }
+
+ private enum PluginInfoToKey implements Function<PluginInfo, String> {
+ INSTANCE;
+
+ @Override
+ public String apply(@Nonnull PluginInfo input) {
+ return input.getKey();
+ }
+ }
+}