]> git.argeo.org Git - gpl/argeo-slc.git/commitdiff
First working Maven proxy
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 21 Sep 2011 18:39:33 +0000 (18:39 +0000)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 21 Sep 2011 18:39:33 +0000 (18:39 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@4750 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

modules/server/org.argeo.slc.server.repo.webapp/META-INF/MANIFEST.MF
modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/applicationContext.xml
modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/maven-servlet.xml
modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/osgi.xml
modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/security.xml [new file with mode: 0644]
modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/web.xml
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyService.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServiceImpl.java [new file with mode: 0644]
runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServlet.java

index 01404071ba3f0457a316b2c34fd5da220f739ae7..04874c01ce8837dcaa61d97a27954c19ef0aa571 100644 (file)
@@ -5,6 +5,28 @@ Bundle-SymbolicName: org.argeo.slc.server.repo.webapp
 Bundle-Version: 0.13.1.SNAPSHOT
 Web-ContextPath: org.argeo.slc.repo.webapp
 Bundle-Vendor: Argeo
-Import-Package: javax.servlet,
+Import-Package: javax.jcr;version="2.0.0",
+ javax.servlet,
  javax.servlet.http,
- javax.servlet.resources
+ javax.servlet.resources,
+ org.argeo.security.core,
+ org.argeo.security.jcr,
+ org.argeo.slc.aether.spring,
+ org.argeo.slc.repo.maven.proxy,
+ org.springframework.osgi.web.context.support;version="1.2.1",
+ org.springframework.security;version="2.0.6.RELEASE",
+ org.springframework.security.context;version="2.0.6.RELEASE",
+ org.springframework.security.intercept.web;version="2.0.6.RELEASE",
+ org.springframework.security.providers.anonymous;version="2.0.6.RELEASE",
+ org.springframework.security.ui;version="2.0.6.RELEASE",
+ org.springframework.security.ui.basicauth;version="2.0.6.RELEASE",
+ org.springframework.security.ui.logout;version="2.0.6.RELEASE",
+ org.springframework.security.ui.rememberme;version="2.0.6.RELEASE",
+ org.springframework.security.userdetails;version="2.0.6.RELEASE",
+ org.springframework.security.util;version="2.0.6.RELEASE",
+ org.springframework.security.vote;version="2.0.6.RELEASE",
+ org.springframework.security.wrapper;version="2.0.6.RELEASE",
+ org.springframework.web.context;version="2.5.6.SEC01",
+ org.springframework.web.filter;version="2.5.6.SEC01",
+ org.springframework.web.servlet;version="2.5.6.SEC01",
+ org.springframework.web.servlet.handler;version="2.5.6.SEC01"
index 38267a458a8d0ed12845eeaaf960dac8e7275b01..a45053fd5decab203e01eb00c6443d7f2c783ebf 100644 (file)
@@ -6,5 +6,6 @@
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
 
        <import resource="osgi.xml" />
+       <import resource="security.xml" />
 
 </beans>
\ No newline at end of file
index 6ab60c58427025bb00f694933e7369277c45c864..0c0d817e32d1d8089518a03b9259126e29d26149 100644 (file)
@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
-       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
+       xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
-               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
-               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
-               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
+       ">
 
        <bean
                class="org.springframework.web.servlet.handler.SimpleServletPostProcessor" />
                class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                <property name="mappings">
                        <props>
-                               <prop key="*">companyRemoteService</prop>
+                               <prop key="*">mavenProxyServlet</prop>
                        </props>
                </property>
        </bean>
 
-       <bean id="mavenProxyServlet"
-               class="com.somecompany.gwt.server.servicesimpl.CompanyRemoteServiceImpl" />
+       <bean id="mavenProxyService" class="org.argeo.slc.repo.maven.proxy.MavenProxyServiceImpl"
+               init-method="init" destroy-method="destroy">
+               <property name="jcrRepository" ref="jcrRepository" />
+               <property name="defaultRepositories" ref="defaultMavenRepositories" />
+       </bean>
+
+       <bean id="mavenProxyServlet" class="org.argeo.slc.repo.maven.proxy.MavenProxyServlet">
+               <property name="jcrSession" ref="jcrSession" />
+               <property name="proxyService" ref="mavenProxyService" />
+       </bean>
+
+       <bean id="jcrSession" class="org.argeo.security.jcr.SecureThreadBoundSession">
+               <property name="repository" ref="jcrRepository" />
+               <property name="defaultUsername" value="root" />
+               <property name="defaultPassword" value="demo" />
+       </bean>
+
+       <bean
+               class="org.argeo.security.core.AuthenticatedApplicationContextInitialization">
+               <property name="authenticationManager" ref="authenticationManager" />
+       </bean>
+
+       <!-- Remote repositories -->
+       <util:list id="defaultMavenRepositories">
+               <ref local="central" />
+               <ref local="com.springsource.repository.bundles.external" />
+               <ref local="com.springsource.repository.bundles.release" />
+               <ref local="argeo" />
+               <ref local="argeo-snapshots" />
+       </util:list>
+
+       <bean id="central" class="org.argeo.slc.aether.spring.RemoteRepositoryFactory">
+               <property name="url" value="http://repo1.maven.org/maven2" />
+       </bean>
+       <bean id="com.springsource.repository.bundles.release" class="org.argeo.slc.aether.spring.RemoteRepositoryFactory">
+               <property name="url"
+                       value="http://repository.springsource.com/maven/bundles/release" />
+       </bean>
+       <bean id="com.springsource.repository.bundles.external" class="org.argeo.slc.aether.spring.RemoteRepositoryFactory">
+               <property name="url"
+                       value="http://repository.springsource.com/maven/bundles/external" />
+       </bean>
+       <bean id="argeo" class="org.argeo.slc.aether.spring.RemoteRepositoryFactory">
+               <property name="url" value="http://maven.argeo.org/argeo/" />
+       </bean>
+       <bean id="argeo-snapshots" class="org.argeo.slc.aether.spring.RemoteRepositoryFactory">
+               <property name="url" value="http://dev.argeo.org/maven/argeo-snapshots/" />
+       </bean>
 
 </beans>
\ No newline at end of file
index 34fe6ad8124244fa189dd0ca9a4eb9f343a21d07..15231c8cb1697e7d2c24b999d82df7cc65c15ec4 100644 (file)
@@ -8,11 +8,14 @@
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.xsd">\r
 \r
-       <set id="repositories" interface="javax.jcr.Repository" cardinality="0..N">\r
-               <listener ref="repositoryRegister" bind-method="register"\r
-                       unbind-method="unregister" />\r
-       </set>\r
+       <!-- REFRENCES -->\r
+       <!-- Security -->\r
+       <reference id="authenticationManager"\r
+               interface="org.springframework.security.AuthenticationManager" />\r
+       <reference id="userDetailsService"\r
+               interface="org.springframework.security.userdetails.UserDetailsService" />\r
 \r
-<!--   <reference id="authenticationManager"-->\r
-<!--           interface="org.springframework.security.AuthenticationManager" />-->\r
+       <!-- JCR -->\r
+       <reference id="jcrRepository" interface="javax.jcr.Repository"\r
+               filter="(argeo.jcr.repository.alias=slc)" />\r
 </beans:beans>
\ No newline at end of file
diff --git a/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/security.xml b/modules/server/org.argeo.slc.server.repo.webapp/WEB-INF/security.xml
new file mode 100644 (file)
index 0000000..340c8e7
--- /dev/null
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.4.xsd">
+
+       <bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
+               <sec:filter-chain-map path-type="ant">
+                       <sec:filter-chain pattern="/**"
+                               filters="httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,anonymousProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor" />
+               </sec:filter-chain-map>
+       </bean>
+
+       <!-- The actual authorization checks (called last, but first here for ease 
+               of configuration) -->
+       <bean id="filterInvocationInterceptor" parent="filterInvocationInterceptorTemplate">
+               <property name="objectDefinitionSource">
+                       <value>
+                               CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
+                               PATTERN_TYPE_APACHE_ANT
+                               /public/**=IS_AUTHENTICATED_ANONYMOUSLY
+                               /**=ROLE_USER
+                       </value>
+                       <!-- <value> -->
+                       <!-- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON -->
+                       <!-- PATTERN_TYPE_APACHE_ANT -->
+                       <!-- /config/**=ROLE_ADMINISTRATOR -->
+                       <!-- /**=IS_AUTHENTICATED_ANONYMOUSLY -->
+                       <!-- </value> -->
+               </property>
+       </bean>
+
+       <!-- Integrates the authentication information in the http sessions -->
+       <bean id="httpSessionContextIntegrationFilter"
+               class="org.springframework.security.context.HttpSessionContextIntegrationFilter">
+               <property name="allowSessionCreation" value="true" />
+       </bean>
+
+       <!-- Processes logouts, removing both session informations and the remember-me 
+               cookie from the browser -->
+       <bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
+               <constructor-arg value="/web/" />
+               <!-- URL redirected to after logout -->
+               <constructor-arg>
+                       <list>
+                               <ref bean="rememberMeServices" />
+                               <bean
+                                       class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />
+                       </list>
+               </constructor-arg>
+       </bean>
+
+       <!-- Double check, this may not be necessary -->
+       <bean id="securityContextHolderAwareRequestFilter"
+               class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter" />
+
+       <!-- Use the remember me cookie to authenticate -->
+       <bean id="rememberMeProcessingFilter"
+               class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
+               <property name="authenticationManager" ref="authenticationManager" />
+               <property name="rememberMeServices" ref="rememberMeServices" />
+       </bean>
+
+       <bean id="rememberMeServices"
+               class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
+               <property name="userDetailsService" ref="userDetailsService" />
+               <property name="key" value="${argeo.security.systemKey}" />
+       </bean>
+
+       <!-- Basic authentication -->
+       <bean id="basicProcessingFilter"
+               class="org.springframework.security.ui.basicauth.BasicProcessingFilter">
+               <property name="authenticationManager">
+                       <ref bean="authenticationManager" />
+               </property>
+               <property name="authenticationEntryPoint">
+                       <ref local="basicProcessingFilterEntryPoint" />
+               </property>
+               <property name="rememberMeServices" ref="rememberMeServices" />
+       </bean>
+
+       <!-- Activate basic auth when needed -->
+       <bean id="basicProcessingFilterEntryPoint"
+               class="org.springframework.security.ui.basicauth.BasicProcessingFilterEntryPoint">
+               <property name="realmName">
+                       <value>Argeo</value>
+               </property>
+       </bean>
+
+       <!-- If everything else failed, anonymous authentication -->
+       <bean id="anonymousProcessingFilter"
+               class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
+               <property name="key" value="${argeo.security.systemKey}" />
+               <property name="userAttribute" value="anonymous,ROLE_ANONYMOUS" />
+       </bean>
+
+       <!-- Reacts to security related exceptions -->
+       <bean id="exceptionTranslationFilter"
+               class="org.springframework.security.ui.ExceptionTranslationFilter">
+               <property name="authenticationEntryPoint">
+                       <ref bean="basicProcessingFilterEntryPoint" />
+               </property>
+               <property name="accessDeniedHandler">
+                       <bean class="org.springframework.security.ui.AccessDeniedHandlerImpl">
+                               <property name="errorPage" value="/accessDenied.jsp" />
+                       </bean>
+               </property>
+       </bean>
+
+       <!-- Template for authorization checks -->
+       <bean id="filterInvocationInterceptorTemplate" abstract="true"
+               class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
+               <property name="authenticationManager" ref="authenticationManager" />
+               <property name="accessDecisionManager">
+                       <bean class="org.springframework.security.vote.AffirmativeBased">
+                               <property name="allowIfAllAbstainDecisions" value="false" />
+                               <property name="decisionVoters">
+                                       <list>
+                                               <bean class="org.springframework.security.vote.RoleVoter" />
+                                               <bean class="org.springframework.security.vote.AuthenticatedVoter" />
+                                       </list>
+                               </property>
+                       </bean>
+               </property>
+       </bean>
+</beans>
\ No newline at end of file
index 7adc82ad331ac083164f195e4310acb3f55e0f31..a998cda0dfd6e442508c4d90daac53beddd96b1c 100644 (file)
                <servlet-name>maven</servlet-name>
                <url-pattern>/maven/*</url-pattern>
        </servlet-mapping>
+
+       <!-- Security -->
+       <filter>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
+       </filter>
+
+       <filter-mapping>
+               <filter-name>springSecurityFilterChain</filter-name>
+               <url-pattern>/*</url-pattern>
+       </filter-mapping>
+
 </web-app>
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyService.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyService.java
new file mode 100644 (file)
index 0000000..a1b7ffb
--- /dev/null
@@ -0,0 +1,8 @@
+package org.argeo.slc.repo.maven.proxy;
+
+/** Synchronizes JCR and Maven repositories */
+public interface MavenProxyService {
+       public String getNodePath(String path);
+
+       public String proxyFile(String path);
+}
diff --git a/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServiceImpl.java b/runtime/org.argeo.slc.repo/src/main/java/org/argeo/slc/repo/maven/proxy/MavenProxyServiceImpl.java
new file mode 100644 (file)
index 0000000..9e2cfd0
--- /dev/null
@@ -0,0 +1,140 @@
+package org.argeo.slc.repo.maven.proxy;
+
+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.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+
+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;
+
+/** Synchronizes the node repository with remote Maven repositories */
+public class MavenProxyServiceImpl implements MavenProxyService, ArgeoNames,
+               SlcNames {
+       private final static Log log = LogFactory
+                       .getLog(MavenProxyServiceImpl.class);
+
+       private Repository jcrRepository;
+       private Session jcrAdminSession;
+       private List<RemoteRepository> defaultRepositories = new ArrayList<RemoteRepository>();
+
+       public void init() {
+               try {
+                       jcrAdminSession = jcrRepository.login();
+
+                       JcrUtils.mkdirs(jcrAdminSession, RepoConstants.ARTIFACTS_BASE_PATH);
+                       Node proxiedRepositories = JcrUtils.mkdirs(jcrAdminSession,
+                                       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());
+                               }
+                       }
+                       jcrAdminSession.save();
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(jcrAdminSession);
+                       throw new SlcException("Cannot initialize Maven proxy", e);
+               }
+       }
+
+       public void destroy() {
+               JcrUtils.logoutQuietly(jcrAdminSession);
+       }
+
+       /**
+        * Retrieve and add this file to the repository
+        */
+       public synchronized String proxyFile(String path) {
+               try {
+                       Node node = null;
+                       proxiedRepositories: for (NodeIterator nit = jcrAdminSession
+                                       .getNode(RepoConstants.PROXIED_REPOSITORIES).getNodes(); nit
+                                       .hasNext();) {
+                               Node proxiedRepository = nit.nextNode();
+                               String repoUrl = proxiedRepository.getProperty(SLC_URL)
+                                               .getString();
+                               String remoteUrl = repoUrl + path;
+                               if (log.isTraceEnabled())
+                                       log.trace("remoteUrl=" + remoteUrl);
+                               InputStream in = null;
+                               try {
+                                       URL u = new URL(remoteUrl);
+                                       in = u.openStream();
+                                       node = importFile(getNodePath(path), in);
+                                       if (log.isDebugEnabled())
+                                               log.debug("Imported " + remoteUrl + " to " + node);
+                                       break proxiedRepositories;
+                               } catch (Exception e) {
+                                       if (log.isDebugEnabled())
+                                               log.debug("Cannot read " + remoteUrl + ", skipping... "
+                                                               + e.getMessage());
+                                       // e.printStackTrace();
+                               } finally {
+                                       IOUtils.closeQuietly(in);
+                               }
+                       }
+
+                       if (node != null)
+                               return node.getIdentifier();
+                       else {
+                               log.warn("Could not proxy " + path);
+                               return null;
+                       }
+               } catch (RepositoryException e) {
+                       throw new SlcException("Cannot proxy " + path, e);
+               }
+       }
+
+       /** The JCR path where this file could be found */
+       public String getNodePath(String path) {
+               return RepoConstants.ARTIFACTS_BASE_PATH + path;
+       }
+
+       protected Node importFile(String nodePath, InputStream in) {
+               Binary binary = null;
+               try {
+                       Node node = JcrUtils.mkdirs(jcrAdminSession, nodePath,
+                                       NodeType.NT_FILE, NodeType.NT_FOLDER, false);
+                       Node content = node.addNode(Node.JCR_CONTENT, NodeType.NT_RESOURCE);
+                       binary = jcrAdminSession.getValueFactory().createBinary(in);
+                       content.setProperty(Property.JCR_DATA, binary);
+                       jcrAdminSession.save();
+                       return node;
+               } catch (RepositoryException e) {
+                       JcrUtils.discardQuietly(jcrAdminSession);
+                       throw new SlcException("Cannot initialize Maven proxy", e);
+               } finally {
+                       JcrUtils.closeQuietly(binary);
+               }
+       }
+
+       public void setJcrRepository(Repository jcrRepository) {
+               this.jcrRepository = jcrRepository;
+       }
+
+       public void setDefaultRepositories(
+                       List<RemoteRepository> defaultRepositories) {
+               this.defaultRepositories = defaultRepositories;
+       }
+
+}
index 39badba89f593d6cc1e605c310a942be8b11e611..acb0fb6c675021fda0df344a2a1ef32f010a8609 100644 (file)
@@ -2,17 +2,12 @@ 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;
@@ -26,8 +21,6 @@ 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
@@ -39,86 +32,46 @@ public class MavenProxyServlet extends HttpServlet implements ArgeoNames,
 
        private final static Log log = LogFactory.getLog(MavenProxyServlet.class);
 
+       private MavenProxyService proxyService;
+
        private Session jcrSession;
-       private List<RemoteRepository> defaultRepositories = new ArrayList<RemoteRepository>();
        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);
+               String nodePath = proxyService.getNodePath(path);
+               if (log.isTraceEnabled())
+                       log.trace("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) {
+                       Node node;
+                       if (!jcrSession.itemExists(nodePath)) {
+                               String nodeIdentifier = proxyService.proxyFile(path);
+                               if (nodeIdentifier == null) {
+                                       //log.warn("Could not proxy " + path);
                                        response.sendError(404);
                                        return;
-                                       // throw new SlcException("Could not find " + path
-                                       // + " among proxies");
+                               } else {
+                                       node = jcrSession.getNodeByIdentifier(nodeIdentifier);
                                }
+                       } else {
+                               node = jcrSession.getNode(nodePath);
                        }
                        processResponse(nodePath, node, response);
                } catch (RepositoryException e) {
                        throw new SlcException("Cannot proxy " + request, e);
                }
-               super.doGet(request, response);
+               //super.doGet(request, response);
        }
 
-       /** Download the content of the node. */
+       /** Retrieve the content of the node. */
        protected void processResponse(String path, Node node,
                        HttpServletResponse response) {
+               Binary binary = null;
+               InputStream in = null;
                try {
                        String fileName = node.getName();
                        String ext = FilenameUtils.getExtension(fileName);
@@ -146,26 +99,25 @@ public class MavenProxyServlet extends HttpServlet implements ArgeoNames,
                        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);
+                       binary = node.getNode(Property.JCR_CONTENT)
+                                       .getProperty(Property.JCR_DATA).getBinary();
+                       in = binary.getStream();
+                       IOUtils.copy(in, response.getOutputStream());
+               } catch (Exception e) {
+                       throw new SlcException("Cannot download " + node, e);
                } finally {
+                       IOUtils.closeQuietly(in);
                        JcrUtils.closeQuietly(binary);
                }
        }
+
+       public void setJcrSession(Session jcrSession) {
+               this.jcrSession = jcrSession;
+       }
+
+       public void setProxyService(MavenProxyService proxyService) {
+               this.proxyService = proxyService;
+       }
+
 }