added api to install plugin packages

This commit is contained in:
Sebastian Sdorra
2012-09-29 21:44:39 +02:00
parent 5c43ece689
commit a5ca1a55d2
6 changed files with 159 additions and 29 deletions

View File

@@ -44,8 +44,10 @@ import sonia.scm.util.IOUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -66,6 +68,30 @@ public class ZipUnArchiver extends AbstractUnArchiver
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param inputStream
* @param outputDirectory
*
* @throws IOException
* @since 1.21
*/
public void extractArchive(InputStream inputStream, File outputDirectory)
throws IOException
{
ZipInputStream input = new ZipInputStream(inputStream);
ZipEntry entry = input.getNextEntry();
while (entry != null)
{
extractEntry(outputDirectory, input, entry);
entry = input.getNextEntry();
}
}
/**
* Method description
*
@@ -85,19 +111,12 @@ public class ZipUnArchiver extends AbstractUnArchiver
outputDirectory.getAbsolutePath());
}
ZipInputStream input = null;
InputStream input = null;
try
{
input = new ZipInputStream(new FileInputStream(archive));
ZipEntry entry = input.getNextEntry();
while (entry != null)
{
extractEntry(outputDirectory, input, entry);
entry = input.getNextEntry();
}
input = new FileInputStream(archive);
extractArchive(input, outputDirectory);
}
finally
{

View File

@@ -35,6 +35,9 @@ package sonia.scm.plugin;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
/**
@@ -58,6 +61,17 @@ public interface PluginManager
*/
public void install(String id);
/**
* Installs a plugin package from a inputstream.
*
*
* @param packageStream package input stream
*
* @throws IOException
* @since 1.21
*/
public void installPackage(InputStream packageStream) throws IOException;
/**
* Method description
*

View File

@@ -107,6 +107,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- injection -->
<dependency>
@@ -203,6 +209,12 @@
<version>${aether.version}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-connector-file</artifactId>
<version>${aether.version}</version>
</dependency>
<!-- rest documentation -->
<dependency>

View File

@@ -47,12 +47,18 @@ import sonia.scm.plugin.PluginInformationComparator;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.multipart.FormDataParam;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -85,6 +91,33 @@ public class PluginResource
//~--- methods --------------------------------------------------------------
/**
* Installs a plugin from a package.<br />
* <br />
* <ul>
* <li>200 success</li>
* <li>500 internal server error</li>
* </ul>
*
*
*
* @param uploadedInputStream
* @return
*
* @throws IOException
*/
@POST
@Path("install-package")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response install(
@FormDataParam("package") InputStream uploadedInputStream)
throws IOException
{
pluginManager.installPackage(uploadedInputStream);
return Response.ok().build();
}
/**
* Installs a plugin.<br />
* <br />

View File

@@ -46,6 +46,7 @@ import org.slf4j.LoggerFactory;
import org.sonatype.aether.RepositorySystem;
import org.sonatype.aether.collection.CollectRequest;
import org.sonatype.aether.connector.async.AsyncRepositoryConnectorFactory;
import org.sonatype.aether.connector.file.FileRepositoryConnectorFactory;
import org.sonatype.aether.graph.Dependency;
import org.sonatype.aether.graph.DependencyFilter;
import org.sonatype.aether.graph.DependencyNode;
@@ -343,6 +344,8 @@ public class AetherPluginHandler
DefaultArtifactDescriptorReader.class);
locator.addService(RepositoryConnectorFactory.class,
AsyncRepositoryConnectorFactory.class);
locator.addService(RepositoryConnectorFactory.class,
FileRepositoryConnectorFactory.class);
return locator.getService(RepositorySystem.class);
}

View File

@@ -35,6 +35,8 @@ package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -49,6 +51,7 @@ import sonia.scm.SCMContextProvider;
import sonia.scm.cache.Cache;
import sonia.scm.cache.CacheManager;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.io.ZipUnArchiver;
import sonia.scm.net.HttpClient;
import sonia.scm.security.SecurityContext;
import sonia.scm.util.AssertUtil;
@@ -59,6 +62,8 @@ import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
@@ -72,6 +77,7 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
@@ -116,8 +122,7 @@ public class DefaultPluginManager
* @param clientProvider
*/
@Inject
public DefaultPluginManager(
SCMContextProvider context,
public DefaultPluginManager(SCMContextProvider context,
Provider<SecurityContext> securityContextProvicer,
ScmConfiguration configuration, PluginLoader pluginLoader,
CacheManager cacheManager, Provider<HttpClient> clientProvider)
@@ -214,6 +219,50 @@ public class DefaultPluginManager
}
}
/**
* Method description
*
*
* @param packageStream
*
* @throws IOException
*/
@Override
public void installPackage(InputStream packageStream) throws IOException
{
SecurityUtil.assertIsAdmin(securityContextProvicer);
File tempDirectory = Files.createTempDir();
try
{
new ZipUnArchiver().extractArchive(packageStream, tempDirectory);
Plugin plugin = JAXB.unmarshal(new File(tempDirectory, "plugin.xml"),
Plugin.class);
// TODO check conditions
AetherPluginHandler aph = new AetherPluginHandler(this, context,
configuration);
Collection<PluginRepository> repositories =
Sets.newHashSet(new PluginRepository("package-repository",
"file://".concat(tempDirectory.getAbsolutePath())));
aph.setPluginRepositories(repositories);
aph.install(plugin.getInformation().getId());
plugin.getInformation().setState(PluginState.INSTALLED);
installedPlugins.put(plugin.getInformation().getId(), plugin);
}
finally
{
IOUtil.delete(tempDirectory);
}
}
/**
* Method description
*