mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-07 14:05:44 +01:00
refactor plugin endpoints
This commit is contained in:
@@ -282,16 +282,6 @@ public class PluginInformation
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Object> getLinks() {
|
||||
return links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -384,17 +374,6 @@ public class PluginInformation
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param links
|
||||
*/
|
||||
public void setLinks(Map<String, Object> links) {
|
||||
this.links = links;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@@ -418,7 +397,4 @@ public class PluginInformation
|
||||
/** Field description */
|
||||
private String version;
|
||||
|
||||
/** Field description */
|
||||
private Map<String, Object> links;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||
import sonia.scm.plugin.Plugin;
|
||||
import sonia.scm.plugin.PluginInformation;
|
||||
import sonia.scm.plugin.PluginLoader;
|
||||
import sonia.scm.plugin.PluginManager;
|
||||
import sonia.scm.plugin.PluginPermissions;
|
||||
import sonia.scm.plugin.PluginState;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
public class AvailablePluginResource {
|
||||
|
||||
private final PluginDtoCollectionMapper collectionMapper;
|
||||
private PluginDtoMapper dtoMapper;
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@Inject
|
||||
public AvailablePluginResource(PluginDtoCollectionMapper collectionMapper, PluginDtoMapper dtoMapper, PluginManager pluginManager) {
|
||||
this.collectionMapper = collectionMapper;
|
||||
this.dtoMapper = dtoMapper;
|
||||
this.pluginManager = pluginManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of available plugins.
|
||||
*
|
||||
* @return collection of available plugins.
|
||||
*/
|
||||
@GET
|
||||
@Path("")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(CollectionDto.class)
|
||||
@Produces(VndMediaType.PLUGIN_COLLECTION)
|
||||
public Response getAvailablePlugins() {
|
||||
PluginPermissions.read().check();
|
||||
Collection<PluginInformation> plugins = pluginManager.getAvailable()
|
||||
.stream()
|
||||
.filter(plugin -> plugin.getState().equals(PluginState.AVAILABLE))
|
||||
.collect(Collectors.toList());
|
||||
return Response.ok(collectionMapper.map(plugins)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns available plugin.
|
||||
*
|
||||
* @return available plugin.
|
||||
*/
|
||||
@GET
|
||||
@Path("/{name}/{version}")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(CollectionDto.class)
|
||||
@Produces(VndMediaType.PLUGIN)
|
||||
public Response getAvailablePlugin(@PathParam("name") String name, @PathParam("version") String version) {
|
||||
PluginPermissions.read().check();
|
||||
Optional<PluginInformation> plugin = pluginManager.getAvailable()
|
||||
.stream()
|
||||
.filter(p -> p.getId().equals(name + ":" + version))
|
||||
.findFirst();
|
||||
return Response.ok(dtoMapper.map(plugin.get())).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 200 when plugin installation is successful triggered.
|
||||
*
|
||||
* @return HTTP Status.
|
||||
*/
|
||||
@POST
|
||||
@Path("/{name}/{version}/install")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(CollectionDto.class)
|
||||
@Produces(VndMediaType.PLUGIN)
|
||||
public Response installPlugin(@PathParam("name") String name, @PathParam("version") String version) {
|
||||
PluginPermissions.manage().check();
|
||||
pluginManager.install(name + ":" + version);
|
||||
return Response.ok().build();
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@ public class IndexDtoGenerator extends HalAppenderMapper {
|
||||
link("logout", resourceLinks.authentication().logout())
|
||||
);
|
||||
if (PluginPermissions.read().isPermitted()) {
|
||||
builder.single(link("plugins", resourceLinks.pluginCollection().self()));
|
||||
builder.single(link("installedPlugins", resourceLinks.installedPluginCollection().self()));
|
||||
builder.single(link("availablePlugins", resourceLinks.availablePluginCollection().self()));
|
||||
}
|
||||
if (UserPermissions.list().isPermitted()) {
|
||||
builder.single(link("users", resourceLinks.userCollection().self()));
|
||||
|
||||
@@ -15,6 +15,7 @@ import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
@@ -28,7 +29,7 @@ import java.util.stream.Collectors;
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
|
||||
public class PluginResource {
|
||||
public class InstalledPluginResource {
|
||||
|
||||
private final PluginLoader pluginLoader;
|
||||
private final PluginDtoCollectionMapper collectionMapper;
|
||||
@@ -36,7 +37,7 @@ public class PluginResource {
|
||||
private final PluginManager pluginManager;
|
||||
|
||||
@Inject
|
||||
public PluginResource(PluginLoader pluginLoader, PluginDtoCollectionMapper collectionMapper, PluginDtoMapper mapper, PluginManager pluginManager) {
|
||||
public InstalledPluginResource(PluginLoader pluginLoader, PluginDtoCollectionMapper collectionMapper, PluginDtoMapper mapper, PluginManager pluginManager) {
|
||||
this.pluginLoader = pluginLoader;
|
||||
this.collectionMapper = collectionMapper;
|
||||
this.mapper = mapper;
|
||||
@@ -70,7 +71,7 @@ public class PluginResource {
|
||||
* @return installed plugin with specified id
|
||||
*/
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@Path("/{id}")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 404, condition = "not found"),
|
||||
@@ -91,27 +92,4 @@ public class PluginResource {
|
||||
throw notFound(entity(Plugin.class, id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a collection of available plugins.
|
||||
*
|
||||
* @return collection of available plugins.
|
||||
*/
|
||||
@GET
|
||||
@Path("/available")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 200, condition = "success"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(CollectionDto.class)
|
||||
@Produces(VndMediaType.PLUGIN_COLLECTION)
|
||||
public Response getAvailablePlugins() {
|
||||
PluginPermissions.read().check();
|
||||
Collection<PluginInformation> plugins = pluginManager.getAvailable()
|
||||
.stream()
|
||||
.filter(plugin -> plugin.getState().equals(PluginState.AVAILABLE))
|
||||
.collect(Collectors.toList());
|
||||
return Response.ok(collectionMapper.map(plugins)).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,16 +27,24 @@ public class PluginDtoCollectionMapper {
|
||||
|
||||
public HalRepresentation map(List<PluginWrapper> plugins) {
|
||||
List<PluginDto> dtos = plugins.stream().map(mapper::map).collect(toList());
|
||||
return new HalRepresentation(createLinks(), embedDtos(dtos));
|
||||
return new HalRepresentation(createInstalledPluginsLinks(), embedDtos(dtos));
|
||||
}
|
||||
|
||||
public HalRepresentation map(Collection<PluginInformation> plugins) {
|
||||
List<PluginDto> dtos = plugins.stream().map(mapper::map).collect(toList());
|
||||
return new HalRepresentation(createLinks(), embedDtos(dtos));
|
||||
return new HalRepresentation(createAvailablePluginsLinks(), embedDtos(dtos));
|
||||
}
|
||||
|
||||
private Links createLinks() {
|
||||
String baseUrl = resourceLinks.pluginCollection().self();
|
||||
private Links createInstalledPluginsLinks() {
|
||||
String baseUrl = resourceLinks.installedPluginCollection().self();
|
||||
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.with(Links.linkingTo().self(baseUrl).build());
|
||||
return linksBuilder.build();
|
||||
}
|
||||
|
||||
private Links createAvailablePluginsLinks() {
|
||||
String baseUrl = resourceLinks.availablePluginCollection().self();
|
||||
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.with(Links.linkingTo().self(baseUrl).build());
|
||||
|
||||
@@ -2,11 +2,11 @@ package sonia.scm.api.v2.resources;
|
||||
|
||||
import de.otto.edison.hal.Links;
|
||||
import sonia.scm.plugin.PluginInformation;
|
||||
import sonia.scm.plugin.PluginState;
|
||||
import sonia.scm.plugin.PluginWrapper;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static de.otto.edison.hal.Link.*;
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
|
||||
public class PluginDtoMapper {
|
||||
@@ -23,13 +23,18 @@ public class PluginDtoMapper {
|
||||
}
|
||||
|
||||
public PluginDto map(PluginInformation pluginInformation) {
|
||||
Links.Builder linksBuilder = linkingTo()
|
||||
.self(resourceLinks.plugin()
|
||||
.self(pluginInformation.getName()));
|
||||
Links.Builder linksBuilder;
|
||||
if (pluginInformation.getState() != null && pluginInformation.getState().equals(PluginState.AVAILABLE)) {
|
||||
linksBuilder = linkingTo()
|
||||
.self(resourceLinks.availablePlugin()
|
||||
.self(pluginInformation.getName(), pluginInformation.getVersion()));
|
||||
|
||||
for (Object link : pluginInformation.getLinks().values()) {
|
||||
System.out.println("Link is = " + link.toString());
|
||||
linksBuilder.item(((Map<String, Object>) link).values().iterator().next().toString());
|
||||
linksBuilder.single(link("install", resourceLinks.availablePlugin().install(pluginInformation.getName(), pluginInformation.getVersion())));
|
||||
}
|
||||
else {
|
||||
linksBuilder = linkingTo()
|
||||
.self(resourceLinks.installedPlugin()
|
||||
.self(pluginInformation.getName()));
|
||||
}
|
||||
|
||||
PluginDto pluginDto = new PluginDto(linksBuilder.build());
|
||||
|
||||
@@ -4,18 +4,23 @@ import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
import javax.ws.rs.Path;
|
||||
|
||||
@Path("v2/")
|
||||
@Path("v2/plugins")
|
||||
public class PluginRootResource {
|
||||
|
||||
private Provider<PluginResource> pluginResourceProvider;
|
||||
private Provider<InstalledPluginResource> installedPluginResourceProvider;
|
||||
private Provider<AvailablePluginResource> availablePluginResourceProvider;
|
||||
|
||||
@Inject
|
||||
public PluginRootResource(Provider<PluginResource> pluginResourceProvider) {
|
||||
this.pluginResourceProvider = pluginResourceProvider;
|
||||
public PluginRootResource(Provider<InstalledPluginResource> installedPluginResourceProvider, Provider<AvailablePluginResource> availablePluginResourceProvider) {
|
||||
this.installedPluginResourceProvider = installedPluginResourceProvider;
|
||||
this.availablePluginResourceProvider = availablePluginResourceProvider;
|
||||
}
|
||||
|
||||
@Path("plugins")
|
||||
public PluginResource plugins() {
|
||||
return pluginResourceProvider.get();
|
||||
@Path("/installed")
|
||||
public InstalledPluginResource installedPlugins() {
|
||||
return installedPluginResourceProvider.get();
|
||||
}
|
||||
|
||||
@Path("/available")
|
||||
public AvailablePluginResource availablePlugins() { return availablePluginResourceProvider.get(); }
|
||||
}
|
||||
|
||||
@@ -651,35 +651,71 @@ class ResourceLinks {
|
||||
}
|
||||
}
|
||||
|
||||
public PluginLinks plugin() {
|
||||
return new PluginLinks(scmPathInfoStore.get());
|
||||
public InstalledPluginLinks installedPlugin() {
|
||||
return new InstalledPluginLinks(scmPathInfoStore.get());
|
||||
}
|
||||
|
||||
static class PluginLinks {
|
||||
private final LinkBuilder pluginLinkBuilder;
|
||||
static class InstalledPluginLinks {
|
||||
private final LinkBuilder installedPluginLinkBuilder;
|
||||
|
||||
PluginLinks(ScmPathInfo pathInfo) {
|
||||
pluginLinkBuilder = new LinkBuilder(pathInfo, PluginRootResource.class, PluginResource.class);
|
||||
InstalledPluginLinks(ScmPathInfo pathInfo) {
|
||||
installedPluginLinkBuilder = new LinkBuilder(pathInfo, PluginRootResource.class, InstalledPluginResource.class);
|
||||
}
|
||||
|
||||
String self(String id) {
|
||||
return pluginLinkBuilder.method("plugins").parameters().method("getInstalledPlugin").parameters(id).href();
|
||||
return installedPluginLinkBuilder.method("installedPlugins").parameters().method("getInstalledPlugin").parameters(id).href();
|
||||
}
|
||||
}
|
||||
|
||||
public PluginCollectionLinks pluginCollection() {
|
||||
return new PluginCollectionLinks(scmPathInfoStore.get());
|
||||
public InstalledPluginCollectionLinks installedPluginCollection() {
|
||||
return new InstalledPluginCollectionLinks(scmPathInfoStore.get());
|
||||
}
|
||||
|
||||
static class PluginCollectionLinks {
|
||||
private final LinkBuilder pluginCollectionLinkBuilder;
|
||||
static class InstalledPluginCollectionLinks {
|
||||
private final LinkBuilder installedPluginCollectionLinkBuilder;
|
||||
|
||||
PluginCollectionLinks(ScmPathInfo pathInfo) {
|
||||
pluginCollectionLinkBuilder = new LinkBuilder(pathInfo, PluginRootResource.class, PluginResource.class);
|
||||
InstalledPluginCollectionLinks(ScmPathInfo pathInfo) {
|
||||
installedPluginCollectionLinkBuilder = new LinkBuilder(pathInfo, PluginRootResource.class, InstalledPluginResource.class);
|
||||
}
|
||||
|
||||
String self() {
|
||||
return pluginCollectionLinkBuilder.method("plugins").parameters().method("getInstalledPlugins").parameters().href();
|
||||
return installedPluginCollectionLinkBuilder.method("installedPlugins").parameters().method("getInstalledPlugins").parameters().href();
|
||||
}
|
||||
}
|
||||
|
||||
public AvailablePluginLinks availablePlugin() {
|
||||
return new AvailablePluginLinks(scmPathInfoStore.get());
|
||||
}
|
||||
|
||||
static class AvailablePluginLinks {
|
||||
private final LinkBuilder availablePluginLinkBuilder;
|
||||
|
||||
AvailablePluginLinks(ScmPathInfo pathInfo) {
|
||||
availablePluginLinkBuilder = new LinkBuilder(pathInfo, PluginRootResource.class, AvailablePluginResource.class);
|
||||
}
|
||||
|
||||
String self(String name, String version) {
|
||||
return availablePluginLinkBuilder.method("availablePlugins").parameters().method("getAvailablePlugin").parameters(name, version).href();
|
||||
}
|
||||
|
||||
String install(String name, String version) {
|
||||
return availablePluginLinkBuilder.method("availablePlugins").parameters().method("installPlugin").parameters(name, version).href();
|
||||
}
|
||||
}
|
||||
|
||||
public AvailablePluginCollectionLinks availablePluginCollection() {
|
||||
return new AvailablePluginCollectionLinks(scmPathInfoStore.get());
|
||||
}
|
||||
|
||||
static class AvailablePluginCollectionLinks {
|
||||
private final LinkBuilder availablePluginCollectionLinkBuilder;
|
||||
|
||||
AvailablePluginCollectionLinks(ScmPathInfo pathInfo) {
|
||||
availablePluginCollectionLinkBuilder = new LinkBuilder(pathInfo, PluginRootResource.class, AvailablePluginResource.class);
|
||||
}
|
||||
|
||||
String self() {
|
||||
return availablePluginCollectionLinkBuilder.method("availablePlugins").parameters().method("getAvailablePlugins").parameters().href();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -186,8 +186,6 @@ public class DefaultPluginManager implements PluginManager
|
||||
|
||||
PluginCenter center = getPluginCenter();
|
||||
|
||||
// pluginHandler.install(id);
|
||||
|
||||
for (PluginInformation plugin : center.getPlugins())
|
||||
{
|
||||
String pluginId = plugin.getId();
|
||||
@@ -593,10 +591,10 @@ public class DefaultPluginManager implements PluginManager
|
||||
*/
|
||||
private PluginCenter getPluginCenter()
|
||||
{
|
||||
PluginCenter center = null; // cache.get(PluginCenter.class.getName());
|
||||
PluginCenter center = cache.get(PluginCenter.class.getName());
|
||||
|
||||
// if (center == null)
|
||||
// {
|
||||
if (center == null)
|
||||
{
|
||||
synchronized (DefaultPluginManager.class)
|
||||
{
|
||||
String pluginUrl = configuration.getPluginUrl();
|
||||
@@ -636,7 +634,7 @@ public class DefaultPluginManager implements PluginManager
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
return center;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public final class PluginCenterDto implements Serializable {
|
||||
private Dependency dependencies;
|
||||
|
||||
@XmlElement(name = "_links")
|
||||
private Map<String, Object> links;
|
||||
private Map<String, Link> links;
|
||||
}
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@@ -77,18 +77,10 @@ public final class PluginCenterDto implements Serializable {
|
||||
private String name;
|
||||
}
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlRootElement(name = "_links")
|
||||
@Getter
|
||||
static class Links {
|
||||
private Link link;
|
||||
private boolean templated;
|
||||
}
|
||||
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@Getter
|
||||
static class Link {
|
||||
private String url;
|
||||
private String href;
|
||||
private boolean templated;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,10 +24,6 @@ public class PluginCenterDtoMapper {
|
||||
pluginInformation.setCondition(new PluginCondition(condition.getMinVersion(), Collections.singletonList(condition.getOs()), condition.getArch()));
|
||||
}
|
||||
|
||||
if (plugin.getLinks() != null) {
|
||||
pluginInformation.setLinks(plugin.getLinks());
|
||||
}
|
||||
|
||||
pluginInformationSet.add(pluginInformation);
|
||||
}
|
||||
return pluginInformationSet;
|
||||
|
||||
@@ -36,8 +36,10 @@ public class ResourceLinksMock {
|
||||
when(resourceLinks.modifications()).thenReturn(new ResourceLinks.ModificationsLinks(uriInfo));
|
||||
when(resourceLinks.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(uriInfo));
|
||||
when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo));
|
||||
when(resourceLinks.pluginCollection()).thenReturn(new ResourceLinks.PluginCollectionLinks(uriInfo));
|
||||
when(resourceLinks.plugin()).thenReturn(new ResourceLinks.PluginLinks(uriInfo));
|
||||
when(resourceLinks.installedPluginCollection()).thenReturn(new ResourceLinks.InstalledPluginCollectionLinks(uriInfo));
|
||||
when(resourceLinks.availablePluginCollection()).thenReturn(new ResourceLinks.AvailablePluginCollectionLinks(uriInfo));
|
||||
when(resourceLinks.installedPlugin()).thenReturn(new ResourceLinks.InstalledPluginLinks(uriInfo));
|
||||
when(resourceLinks.availablePlugin()).thenReturn(new ResourceLinks.AvailablePluginLinks(uriInfo));
|
||||
when(resourceLinks.uiPluginCollection()).thenReturn(new ResourceLinks.UIPluginCollectionLinks(uriInfo));
|
||||
when(resourceLinks.uiPlugin()).thenReturn(new ResourceLinks.UIPluginLinks(uriInfo));
|
||||
when(resourceLinks.authentication()).thenReturn(new ResourceLinks.AuthenticationLinks(uriInfo));
|
||||
|
||||
Reference in New Issue
Block a user