From e1dc41316d19aedd4d03e459f143b8fddf0e7d75 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 7 Jun 2011 08:17:24 +0000 Subject: [PATCH] Start working on repo git-svn-id: https://svn.argeo.org/slc/trunk@4564 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../WEB-INF/applicationContext.xml | 10 + .../WEB-INF/maven-servlet.xml | 28 +++ .../WEB-INF/osgi.xml | 18 ++ .../WEB-INF/web.xml | 37 ++++ .../org/argeo/slc/repo/RepoConstants.java | 7 + .../java/org/argeo/slc/repo/RepoNames.java | 41 +---- .../java/org/argeo/slc/repo/RepoTypes.java | 19 +- .../repo/maven/ImportMavenDependencies.java | 3 +- .../repo/maven/proxy/MavenProxyServlet.java | 171 ++++++++++++++++++ .../main/java/org/argeo/slc/jcr/SlcNames.java | 33 ++++ .../main/java/org/argeo/slc/jcr/SlcTypes.java | 14 ++ runtime/org.argeo.slc.support.maven/pom.xml | 4 +- runtime/org.argeo.slc.support.simple/pom.xml | 4 +- 13 files changed, 339 insertions(+), 50 deletions(-) create mode 100644 modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/applicationContext.xml create mode 100644 modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/maven-servlet.xml create mode 100644 modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/osgi.xml create mode 100644 modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/web.xml create mode 100644 runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java create mode 100644 runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServlet.java diff --git a/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/applicationContext.xml b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/applicationContext.xml new file mode 100644 index 000000000..38267a458 --- /dev/null +++ b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/applicationContext.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/maven-servlet.xml b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/maven-servlet.xml new file mode 100644 index 000000000..6ab60c584 --- /dev/null +++ b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/maven-servlet.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + companyRemoteService + + + + + + + \ No newline at end of file diff --git a/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/osgi.xml b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/osgi.xml new file mode 100644 index 000000000..34fe6ad81 --- /dev/null +++ b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/osgi.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/web.xml b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/web.xml new file mode 100644 index 000000000..7adc82ad3 --- /dev/null +++ b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/web.xml @@ -0,0 +1,37 @@ + + + + Argeo SLC Repo Webapp + + + + contextConfigLocation + /WEB-INF/applicationContext.xml + + + + Spring Context + org.springframework.web.context.ContextLoaderListener + + + contextClass + org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + + + + + maven + org.springframework.web.servlet.DispatcherServlet + + contextClass + org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext + + 1 + + + maven + /maven/* + + diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java new file mode 100644 index 000000000..0cbfcf475 --- /dev/null +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoConstants.java @@ -0,0 +1,7 @@ +package org.argeo.slc.repo; + +/** SLC repository constants */ +public interface RepoConstants { + public final static String ARTIFACTS_BASE_PATH = "/slc/repo/artifacts"; + public final static String PROXIED_REPOSITORIES = "/slc/repo/proxiedRepositories"; +} diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java index 0a69b3d00..e85650611 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoNames.java @@ -1,36 +1,11 @@ package org.argeo.slc.repo; -/** Names used for items (nodes and properties). */ -public interface RepoNames { - public final static String SLC_ = "slc:"; - - // shared - public final static String SLC_NAME = "slc:name"; - public final static String SLC_VERSION = "slc:version"; - public final static String SLC_OPTIONAL = "slc:optional"; - public final static String SLC_AS_STRING = "slc:asString"; - - // slc:artifact - public final static String SLC_ARTIFACT_ID = "slc:artifactId"; - public final static String SLC_GROUP_ID = "slc:groupId"; - public final static String SLC_ARTIFACT_VERSION = "slc:artifactVersion"; - public final static String SLC_ARTIFACT_EXTENSION = "slc:artifactExtension"; - public final static String SLC_ARTIFACT_CLASSIFIER = "slc:artifactClassifier"; - - // slc:jarArtifact - public final static String SLC_MANIFEST = "slc:manifest"; - - // shared OSGi - public final static String SLC_SYMBOLIC_NAME = "slc:symbolic-name"; - public final static String SLC_BUNDLE_VERSION = "slc:bundle-version"; - - // slc:osgiBaseVersion - public final static String SLC_MAJOR = "slc:major"; - public final static String SLC_MINOR = "slc:minor"; - public final static String SLC_MICRO = "slc:micro"; - // slc:osgiVersion - public final static String SLC_QUALIFIER = "slc:qualifier"; - - // slc:exportedPackage - public final static String SLC_USES = "slc:uses"; +import org.argeo.slc.jcr.SlcNames; + +/** + * Names used for items (nodes and properties). + * + * @deprecated use {@link SlcNames} instead + */ +public interface RepoNames extends SlcNames { } diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java index 5f13d4538..92e538ef5 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/RepoTypes.java @@ -1,16 +1,11 @@ package org.argeo.slc.repo; -/** Node types used programatically. */ -public interface RepoTypes { +import org.argeo.slc.jcr.SlcTypes; - public final static String SLC_ARTIFACT = "slc:artifact"; - public final static String SLC_JAR_FILE = "slc:jarFile"; - public final static String SLC_BUNDLE_ARTIFACT = "slc:bundleArtifact"; - public final static String SLC_OSGI_VERSION = "slc:osgiVersion"; - public final static String SLC_JAVA_PACKAGE = "slc:javaPackage"; - public final static String SLC_EXPORTED_PACKAGE = "slc:exportedPackage"; - public final static String SLC_IMPORTED_PACKAGE = "slc:importedPackage"; - public final static String SLC_DYNAMIC_IMPORTED_PACKAGE = "slc:dynamicImportedPackage"; - public final static String SLC_REQUIRED_BUNDLE = "slc:requiredBundle"; - public final static String SLC_FRAGMENT_HOST = "slc:fragmentHost"; +/** + * Node types used programatically. + * + * @deprecated use {@link SlcTypes} instead + */ +public interface RepoTypes extends SlcTypes { } diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java index 8d5ff5ae2..6f9078fb0 100644 --- a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/ImportMavenDependencies.java @@ -35,6 +35,7 @@ import org.apache.commons.logging.LogFactory; import org.argeo.jcr.JcrUtils; import org.argeo.slc.SlcException; import org.argeo.slc.aether.AetherTemplate; +import org.argeo.slc.repo.RepoConstants; import org.argeo.slc.repo.RepoNames; import org.argeo.slc.repo.RepoTypes; import org.osgi.framework.Constants; @@ -55,7 +56,7 @@ public class ImportMavenDependencies implements Runnable { private Set excludedArtifacts = new HashSet(); private Session jcrSession; - private String artifactBasePath = "/slc/repo/artifacts"; + private String artifactBasePath = RepoConstants.ARTIFACTS_BASE_PATH; private String distributionsBasePath = "/slc/repo/distributions"; private String distributionName; diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServlet.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServlet.java new file mode 100644 index 000000000..39badba89 --- /dev/null +++ b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServlet.java @@ -0,0 +1,171 @@ +package org.argeo.slc.repo.maven.proxy; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.jcr.ArgeoNames; +import org.argeo.jcr.JcrUtils; +import org.argeo.slc.SlcException; +import org.argeo.slc.jcr.SlcNames; +import org.argeo.slc.repo.RepoConstants; +import org.sonatype.aether.repository.RemoteRepository; + +/** + * Expose the SLC repository as a regular Maven repository, proxying third party + * repositories as well. + */ +public class MavenProxyServlet extends HttpServlet implements ArgeoNames, + SlcNames { + private static final long serialVersionUID = 5296857859305486588L; + + private final static Log log = LogFactory.getLog(MavenProxyServlet.class); + + private Session jcrSession; + private List defaultRepositories = new ArrayList(); + private String contentTypeCharset = "UTF-8"; + + @Override + public void init() throws ServletException { + try { + Node proxiedRepositories = JcrUtils.mkdirs(jcrSession, + RepoConstants.PROXIED_REPOSITORIES); + for (RemoteRepository repository : defaultRepositories) { + if (!proxiedRepositories.hasNode(repository.getId())) { + Node proxiedRepository = proxiedRepositories + .addNode(repository.getId()); + proxiedRepository.setProperty(SLC_URL, repository.getUrl()); + proxiedRepository.setProperty(SLC_TYPE, + repository.getContentType()); + } + } + jcrSession.save(); + } catch (RepositoryException e) { + JcrUtils.discardQuietly(jcrSession); + throw new SlcException("Cannot initialize Maven proxy", e); + } + } + + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + String path = request.getPathInfo(); + + String nodePath = RepoConstants.ARTIFACTS_BASE_PATH + path; + if (log.isDebugEnabled()) + log.debug("path=" + path + ", nodePath=" + nodePath); + + try { + Node node = null; + if (jcrSession.itemExists(nodePath)) { + node = jcrSession.getNode(nodePath); + } else { + proxiedRepositories: for (NodeIterator nit = jcrSession + .getNode(RepoConstants.PROXIED_REPOSITORIES).getNodes(); nit + .hasNext();) { + Node proxiedRepository = nit.nextNode(); + String repoUrl = proxiedRepository.getProperty(SLC_URL) + .getString(); + String remoteUrl = repoUrl + path; + if (log.isDebugEnabled()) + log.debug("remoteUrl=" + remoteUrl); + InputStream in = null; + try { + URL u = new URL(remoteUrl); + in = u.openStream(); + node = importFile(nodePath, in); + break proxiedRepositories; + } catch (Exception e) { + if (log.isTraceEnabled()) + log.trace("Cannot read " + remoteUrl + + ", skipping..."); + } finally { + IOUtils.closeQuietly(in); + } + } + + if (node == null) { + response.sendError(404); + return; + // throw new SlcException("Could not find " + path + // + " among proxies"); + } + } + processResponse(nodePath, node, response); + } catch (RepositoryException e) { + throw new SlcException("Cannot proxy " + request, e); + } + super.doGet(request, response); + } + + /** Download the content of the node. */ + protected void processResponse(String path, Node node, + HttpServletResponse response) { + try { + String fileName = node.getName(); + String ext = FilenameUtils.getExtension(fileName); + + // TODO use a more generic / standard approach + // see http://svn.apache.org/viewvc/tomcat/trunk/conf/web.xml + String contentType; + if ("xml".equals(ext)) + contentType = "text/xml;charset=" + contentTypeCharset; + else if ("jar".equals(ext)) + contentType = "application/java-archive"; + else if ("zip".equals(ext)) + contentType = "application/zip"; + else if ("gz".equals(ext)) + contentType = "application/x-gzip"; + else if ("tar".equals(ext)) + contentType = "application/x-tar"; + else + contentType = "application/octet-stream"; + contentType = contentType + ";name=\"" + fileName + "\""; + response.setHeader("Content-Disposition", "attachment; filename=\"" + + fileName + "\""); + response.setHeader("Expires", "0"); + response.setHeader("Cache-Control", "no-cache, must-revalidate"); + response.setHeader("Pragma", "no-cache"); + + response.setContentType(contentType); + } catch (RepositoryException e) { + throw new SlcException("Cannot download " + node, e); + } + } + + protected Node importFile(String nodePath, InputStream in) { + Binary binary = null; + try { + Node node = JcrUtils.mkdirs(jcrSession, nodePath, NodeType.NT_FILE, + NodeType.NT_FOLDER, false); + Node content = node.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE); + binary = jcrSession.getValueFactory().createBinary(in); + content.setProperty(Property.JCR_DATA, binary); + jcrSession.save(); + return node; + } catch (RepositoryException e) { + JcrUtils.discardQuietly(jcrSession); + throw new SlcException("Cannot initialize Maven proxy", e); + } finally { + JcrUtils.closeQuietly(binary); + } + } +} diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java index f1ff9c1a8..3330fd433 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcNames.java @@ -2,6 +2,7 @@ package org.argeo.slc.jcr; /** JCR names used by SLC */ public interface SlcNames { + public final static String SLC_ = "slc:"; public final static String SLC_UUID = "slc:uuid"; public final static String SLC_STATUS = "slc:status"; @@ -29,4 +30,36 @@ public interface SlcNames { public final static String SLC_TAG = "slc:tag"; public final static String SLC_ERROR_MESSAGE = "slc:errorMessage"; + /* + * REPO + */ + // shared + public final static String SLC_URL = "slc:url"; + public final static String SLC_OPTIONAL = "slc:optional"; + public final static String SLC_AS_STRING = "slc:asString"; + + // slc:artifact + public final static String SLC_ARTIFACT_ID = "slc:artifactId"; + public final static String SLC_GROUP_ID = "slc:groupId"; + public final static String SLC_ARTIFACT_VERSION = "slc:artifactVersion"; + public final static String SLC_ARTIFACT_EXTENSION = "slc:artifactExtension"; + public final static String SLC_ARTIFACT_CLASSIFIER = "slc:artifactClassifier"; + + // slc:jarArtifact + public final static String SLC_MANIFEST = "slc:manifest"; + + // shared OSGi + public final static String SLC_SYMBOLIC_NAME = "slc:symbolic-name"; + public final static String SLC_BUNDLE_VERSION = "slc:bundle-version"; + + // slc:osgiBaseVersion + public final static String SLC_MAJOR = "slc:major"; + public final static String SLC_MINOR = "slc:minor"; + public final static String SLC_MICRO = "slc:micro"; + // slc:osgiVersion + public final static String SLC_QUALIFIER = "slc:qualifier"; + + // slc:exportedPackage + public final static String SLC_USES = "slc:uses"; + } diff --git a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java index 5996b9331..382f2a855 100644 --- a/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java +++ b/runtime/org.argeo.slc.support.jcr/src/main/java/org/argeo/slc/jcr/SlcTypes.java @@ -20,4 +20,18 @@ public interface SlcTypes { public final static String SLC_CHECK = "slc:check"; public final static String SLC_PROPERTY = "slc:property"; + /* + * REPO + */ + public final static String SLC_ARTIFACT = "slc:artifact"; + public final static String SLC_JAR_FILE = "slc:jarFile"; + public final static String SLC_BUNDLE_ARTIFACT = "slc:bundleArtifact"; + public final static String SLC_OSGI_VERSION = "slc:osgiVersion"; + public final static String SLC_JAVA_PACKAGE = "slc:javaPackage"; + public final static String SLC_EXPORTED_PACKAGE = "slc:exportedPackage"; + public final static String SLC_IMPORTED_PACKAGE = "slc:importedPackage"; + public final static String SLC_DYNAMIC_IMPORTED_PACKAGE = "slc:dynamicImportedPackage"; + public final static String SLC_REQUIRED_BUNDLE = "slc:requiredBundle"; + public final static String SLC_FRAGMENT_HOST = "slc:fragmentHost"; + } diff --git a/runtime/org.argeo.slc.support.maven/pom.xml b/runtime/org.argeo.slc.support.maven/pom.xml index a69e2cca6..3d3dab348 100644 --- a/runtime/org.argeo.slc.support.maven/pom.xml +++ b/runtime/org.argeo.slc.support.maven/pom.xml @@ -12,8 +12,8 @@ bundle SLC Support Maven - 1.9 - 3.0.2 + 1.11 + 3.0.3 1.0-beta-7 diff --git a/runtime/org.argeo.slc.support.simple/pom.xml b/runtime/org.argeo.slc.support.simple/pom.xml index 305e49cee..2335b5360 100644 --- a/runtime/org.argeo.slc.support.simple/pom.xml +++ b/runtime/org.argeo.slc.support.simple/pom.xml @@ -81,8 +81,8 @@ - org.freecompany.redline - org.argeo.dep.org.freecompany.redline + org.argeo.dep.osgi + org.redline_rpm -- 2.39.2