import com.google.common.collect.ImmutableSortedSet;
import com.google.common.io.Resources;
+import java.util.Collection;
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.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.updatecenter.common.PluginUpdate;
-
-import java.util.Collection;
+import org.sonar.updatecenter.common.UpdateCenter;
import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_UPDATE_ORDERING;
public void define(WebService.NewController controller) {
controller.createAction("available")
.setDescription("Get the list of all the plugins available for installation on the SonarQube instance, sorted by plugin name." +
+ "<br/>" +
+ "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." +
"<br/>" +
"Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]")
.setSince("5.2")
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.beginObject();
- writePlugins(jsonWriter);
+ UpdateCenter updateCenter = updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
+
+ writePlugins(jsonWriter, updateCenter);
+ pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter);
+
+ jsonWriter.endObject();
jsonWriter.close();
}
- private void writePlugins(JsonWriter jsonWriter) {
- jsonWriter.name(ARRAY_PLUGINS);
- jsonWriter.beginArray();
- for (PluginUpdate pluginUpdate : retrieveAvailablePlugins()) {
+ private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) {
+ jsonWriter.name(ARRAY_PLUGINS).beginArray();
+ for (PluginUpdate pluginUpdate : retrieveAvailablePlugins(updateCenter)) {
pluginWSCommons.writePluginUpdate(jsonWriter, pluginUpdate);
}
jsonWriter.endArray();
- jsonWriter.endObject();
}
- private Collection<PluginUpdate> retrieveAvailablePlugins() {
+ private Collection<PluginUpdate> retrieveAvailablePlugins(UpdateCenter updateCenter) {
return ImmutableSortedSet.copyOf(
- NAME_KEY_PLUGIN_UPDATE_ORDERING,
- updateCenterFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH).findAvailablePlugins()
- );
+ NAME_KEY_PLUGIN_UPDATE_ORDERING,
+ updateCenter.findAvailablePlugins()
+ );
}
+
}
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 javax.annotation.Nonnull;
import java.util.Comparator;
static final String OBJECT_UPDATE = "update";
static final String OBJECT_RELEASE = "release";
static final String ARRAY_REQUIRES = "requires";
+ static final String PROPERTY_UPDATE_CENTER_REFRESH = "updateCenterRefresh";
public static final Ordering<PluginMetadata> NAME_KEY_PLUGIN_METADATA_COMPARATOR = Ordering.natural()
.onResultOf(PluginMetadataToName.INSTANCE)
.compound(Ordering.natural().onResultOf(PluginMetadataToKey.INSTANCE));
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)
- );
+ .onResultOf(PluginToName.INSTANCE)
+ .compound(
+ Ordering.from(CASE_INSENSITIVE_ORDER).onResultOf(PluginToKey.INSTANCE)
+ );
public static final Comparator<PluginUpdate> NAME_KEY_PLUGIN_UPDATE_ORDERING = Ordering.from(NAME_KEY_PLUGIN_ORDERING)
.onResultOf(PluginUpdateToPlugin.INSTANCE);
}
}
+ /**
+ * Write properties of the specified UpdateCenter to the specified JsonWriter.
+ * <pre>
+ * "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;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
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.user.UserSession;
import org.sonar.updatecenter.common.PluginUpdate;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
import static java.lang.String.format;
/**
WebService.NewAction action = controller.createAction("update")
.setPost(true)
.setDescription("Updates a plugin specified by its key to the latest version compatible with the SonarQube instance." +
- "<br/>" +
- "Requires user to be authenticated with Administer System permissions")
+ "<br/>" +
+ "Requires user to be authenticated with Administer System permissions")
.setHandler(this);
action.createParam(PARAM_KEY)
*/
package org.sonar.server.plugins.ws;
-import com.google.common.base.Function;
-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;
import org.sonar.server.plugins.ws.PluginUpdateAggregator.PluginUpdateAggregate;
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;
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Ordering;
+import com.google.common.io.Resources;
/**
* Implementation of the {@code updates} action for the Plugins WebService.
"br/>" +
"Each newer version is listed, ordered from the oldest to the newest, with its own update/compatibility status." +
"<br/>" +
+ "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." +
+ "<br/>" +
"Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]")
.setSince("5.2")
.setHandler(this)
JsonWriter jsonWriter = response.newJsonWriter();
jsonWriter.beginObject();
- writePlugins(jsonWriter);
+ UpdateCenter updateCenter = updateCenterMatrixFactory.getUpdateCenter(DO_NOT_FORCE_REFRESH);
+
+ writePlugins(jsonWriter, updateCenter);
+
+ pluginWSCommons.writeUpdateCenterProperties(jsonWriter, updateCenter);
+ jsonWriter.endObject();
jsonWriter.close();
}
- private void writePlugins(JsonWriter jsonWriter) {
+ private void writePlugins(JsonWriter jsonWriter, UpdateCenter updateCenter) {
jsonWriter.name(ARRAY_PLUGINS);
jsonWriter.beginArray();
for (PluginUpdateAggregate aggregate : retrieveUpdatablePlugins()) {
writePluginUpdateAggregate(jsonWriter, aggregate);
}
jsonWriter.endArray();
- jsonWriter.endObject();
}
private void writePluginUpdateAggregate(JsonWriter jsonWriter, PluginUpdateAggregate aggregate) {
]
}
}
- ]
+ ],
+ "updateCenterRefresh": "2015-04-24T16:08:36+0200"
}
\ No newline at end of file
*/
package org.sonar.server.plugins.ws;
+import java.net.URL;
import org.junit.Before;
import org.sonar.api.server.ws.Request;
+import org.sonar.api.utils.DateUtils;
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 java.net.URL;
-
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
protected static final Plugin PLUGIN_1 = new Plugin("p_key_1").setName("p_name_1");
protected static final Plugin PLUGIN_2 = new Plugin("p_key_2").setName("p_name_2").setDescription("p_desc_2");
-
protected UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class);
protected UpdateCenter updateCenter = mock(UpdateCenter.class);
protected Request request = mock(Request.class);
@Before
public void wireMocksTogether() throws Exception {
when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(updateCenter);
+ when(updateCenter.getDate()).thenReturn(DateUtils.parseDateTime("2015-04-24T16:08:36+0200"));
}
}
public class AvailablePluginsWsActionTest extends AbstractUpdateCenterBasedPluginsWsActionTest {
private static final Plugin FULL_PROPERTIES_PLUGIN = new Plugin("p_key")
- .setName("p_name")
- .setCategory("p_category")
- .setDescription("p_description")
- .setLicense("p_license")
- .setOrganization("p_orga_name")
- .setOrganizationUrl("p_orga_url")
- .setTermsConditionsUrl("p_t_and_c_url");
+ .setName("p_name")
+ .setCategory("p_category")
+ .setDescription("p_description")
+ .setLicense("p_license")
+ .setOrganization("p_orga_name")
+ .setOrganizationUrl("p_orga_url")
+ .setTermsConditionsUrl("p_t_and_c_url");
private static final Release FULL_PROPERTIES_PLUGIN_RELEASE = release(FULL_PROPERTIES_PLUGIN, "1.12.1")
- .setDate(DateUtils.parseDate("2015-04-16"))
- .setDownloadUrl("http://p_file.jar")
- .addOutgoingDependency(release(PLUGIN_1, "0.3.6"))
- .addOutgoingDependency(release(PLUGIN_2, "1.0.0"));
+ .setDate(DateUtils.parseDate("2015-04-16"))
+ .setDownloadUrl("http://p_file.jar")
+ .addOutgoingDependency(release(PLUGIN_1, "0.3.6"))
+ .addOutgoingDependency(release(PLUGIN_2, "1.0.0"));
private AvailablePluginsWsAction underTest = new AvailablePluginsWsAction(updateCenterFactory, new PluginWSCommons());
underTest.handle(request, response);
assertJson(response.outputAsString()).isSimilarTo(
- "{" +
- " \"plugins\": [" +
- " {" +
- " \"update\": {" +
- " \"status\": \"" + expectedValue + "\"" +
- " }" +
- " }" +
- " ]" +
- "}"
- );
+ "{" +
+ " \"plugins\": [" +
+ " {" +
+ " \"update\": {" +
+ " \"status\": \"" + expectedValue + "\"" +
+ " }" +
+ " }" +
+ " ]" +
+ "}"
+ );
}
@Test
public void plugins_are_sorted_by_name_then_key_and_made_unique() throws Exception {
when(updateCenter.findAvailablePlugins()).thenReturn(of(
- pluginUpdate("key2", "name2"),
- pluginUpdate("key1", "name2"),
- pluginUpdate("key2", "name2"),
- pluginUpdate("key0", "name0"),
- pluginUpdate("key1", "name1")
- ));
+ pluginUpdate("key2", "name2"),
+ pluginUpdate("key1", "name2"),
+ pluginUpdate("key2", "name2"),
+ pluginUpdate("key0", "name0"),
+ pluginUpdate("key1", "name1")
+ ));
}
}
]
}
}
- ]
+ ],
+ "updateCenterRefresh": "2015-04-24T16:08:36+0200"
}