From: Brett Porter Date: Thu, 6 Jul 2006 11:41:26 +0000 (+0000) Subject: [MRM-117] proxy web interface X-Git-Tag: archiva-0.9-alpha-1~789 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f8ed8907afcf31191fb0753a6d7632574c5954e6;p=archiva.git [MRM-117] proxy web interface Submitted by: Pete Marvin King git-svn-id: https://svn.apache.org/repos/asf/maven/repository-manager/trunk@419527 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/maven-repository-webapp/pom.xml b/maven-repository-webapp/pom.xml index d3d80f162..f275853b0 100644 --- a/maven-repository-webapp/pom.xml +++ b/maven-repository-webapp/pom.xml @@ -59,6 +59,10 @@ org.apache.maven.repository maven-repository-configuration + + org.apache.maven.repository + maven-repository-proxy + org.apache.maven.repository maven-repository-artifact-applet diff --git a/maven-repository-webapp/src/main/java/org/apache/maven/repository/proxy/web/action/RepositoryProxyAction.java b/maven-repository-webapp/src/main/java/org/apache/maven/repository/proxy/web/action/RepositoryProxyAction.java new file mode 100644 index 000000000..fa4f64393 --- /dev/null +++ b/maven-repository-webapp/src/main/java/org/apache/maven/repository/proxy/web/action/RepositoryProxyAction.java @@ -0,0 +1,154 @@ +package org.apache.maven.repository.proxy.web.action; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.opensymphony.xwork.Action; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.maven.repository.proxy.ProxyException; +import org.apache.maven.repository.proxy.ProxyManager; +import org.apache.maven.repository.proxy.configuration.MavenProxyPropertyLoader; +import org.apache.maven.repository.proxy.configuration.ProxyConfiguration; +import org.apache.maven.repository.proxy.configuration.ValidationException; +import org.apache.maven.wagon.ResourceDoesNotExistException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.MalformedURLException; + +/** + * This is the Action class responsible for processing artifact request, + * relies on the RestfulActionMapper to map the artifact request to this action. + * + * @plexus.component role="com.opensymphony.xwork.Action" role-hint="org.apache.maven.repository.manager.web.action.RepositoryProxyAction" + */ +public class RepositoryProxyAction + implements Action +{ + /** + * logger instance + */ + protected static final Log log = LogFactory.getLog( RepositoryProxyAction.class ); + + public static final String NOTFOUND = "notFound"; + + public static final String PROXYERROR = "proxyError"; + + /** + * file requested by the client, + * TODO: validate the requestd file using na interceptor + */ + private String requestedFile; + + /** + * main proxy logic + * + * @plexus.requirement role="org.apache.maven.repository.proxy.ProxyManager" + */ + private ProxyManager repositoryProxyManager; + + /** + * configuration for the ProxyManager + * + * @plexus.requirement + */ + private ProxyConfiguration proxyConfig; + + /** + * the inputstream for the artifact file + */ + private FileInputStream artifactStream; + + /** + * the cached artifact file + */ + private File cachedFile; + + /** + * proxy configuration file + * TODO: recode the configuration part when Configuration is finalized + * TODO: this is only temporary + */ + private String configFile; + + // setters and getters + + public void setProxyManager( ProxyManager manager ) + { + repositoryProxyManager = manager; + } + + public void setRequestedFile( String reqFile ) + { + requestedFile = reqFile; + } + + public String getRequestedFile() + { + return requestedFile; + } + + public FileInputStream getArtifactStream() + { + return artifactStream; + } + + public File getCachedFile() + { + return cachedFile; + } + + public void setConfigFile( String fileName ) + { + configFile = fileName; + } + + /** + * entry-point + */ + public String execute() + throws MalformedURLException, IOException, ValidationException + { + try + { + MavenProxyPropertyLoader loader = new MavenProxyPropertyLoader(); + proxyConfig = loader.load( new FileInputStream( configFile ) ); + repositoryProxyManager.setConfiguration( proxyConfig ); + cachedFile = repositoryProxyManager.get( requestedFile ); + artifactStream = new FileInputStream( cachedFile ); + } + catch ( ResourceDoesNotExistException ex ) + { + log.info( "[not found] " + ex.getMessage() ); + return NOTFOUND; + } + catch ( ProxyException ex ) + { + log.info( "[proxy error] " + ex.getMessage() ); + return PROXYERROR; + } + catch ( FileNotFoundException ex ) + { + log.info( "[not found] " + ex.getMessage() ); + return NOTFOUND; + } + + return SUCCESS; + } +} diff --git a/maven-repository-webapp/src/main/java/org/apache/maven/repository/proxy/web/actionmapper/RepositoryProxyActionMapper.java b/maven-repository-webapp/src/main/java/org/apache/maven/repository/proxy/web/actionmapper/RepositoryProxyActionMapper.java new file mode 100644 index 000000000..33fe1bc0e --- /dev/null +++ b/maven-repository-webapp/src/main/java/org/apache/maven/repository/proxy/web/actionmapper/RepositoryProxyActionMapper.java @@ -0,0 +1,133 @@ +package org.apache.maven.repository.proxy.web.actionmapper; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.opensymphony.webwork.dispatcher.mapper.ActionMapping; +import com.opensymphony.webwork.dispatcher.mapper.DefaultActionMapper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.servlet.http.HttpServletRequest; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.Properties; + +public class RepositoryProxyActionMapper + extends DefaultActionMapper +{ + /** + * logger instance + */ + protected static final Log log = LogFactory.getLog( RepositoryProxyActionMapper.class ); + + private static final String configFileName = "maven-proxy-complete.conf"; + + private static final String defaultProxyAction = "proxy"; + + /** + * the keyword that will be checked on the http request to determine if proxy + * is requested + *

+ * the default prefix is "/proxy/" + */ + private String prefix = "/proxy/"; + + private String requestedArtifact; + + String configFile = null; + + public String getPrefix() + { + return prefix; + } + + public String getRequestedArtifact() + { + return requestedArtifact; + } + + public ActionMapping getDefaultActionMapping( HttpServletRequest request ) + { + ActionMapping mapping = super.getMapping( request ); + + return mapping; + } + + public void setConfigfile( String fileName ) + { + configFile = fileName; + } + + /** + * only process the request that matches the prefix all other request + * will be hand over to the default action mapper + *

+ * if the configuration file is missing the request will also be channeled + * to the default action mapper + */ + public ActionMapping getMapping( HttpServletRequest request ) + { + Properties config = new Properties(); + String uri = request.getServletPath(); + URL configURL = getClass().getClassLoader().getResource( configFileName ); + + if ( ( configURL != null ) && ( configFile == null ) ) + { + configFile = configURL.getFile(); + log.info( configFile ); + } + + try + { + config.load( new FileInputStream( configFile ) ); + } + catch ( IOException ex ) + { + log.info( "[config error] " + ex.getMessage() ); + return getDefaultActionMapping( request ); + } + + if ( config.getProperty( "prefix" ) != null ) + { + prefix = "/" + config.getProperty( "prefix" ) + "/"; + } + + log.info( "prefix : " + prefix ); + + if ( uri.startsWith( prefix ) ) + { + requestedArtifact = uri.substring( prefix.length() ); + + if ( ( requestedArtifact == null ) || ( requestedArtifact.length() < 0 ) ) + { + return getDefaultActionMapping( request ); + } + + HashMap parameterMap = new HashMap(); + + parameterMap.put( "requestedFile", requestedArtifact ); + parameterMap.put( "configFile", configFile ); + + return new ActionMapping( defaultProxyAction, "/", "", parameterMap ); + } + + return getDefaultActionMapping( request ); + } + +} diff --git a/maven-repository-webapp/src/main/resources/maven-proxy-complete.conf b/maven-repository-webapp/src/main/resources/maven-proxy-complete.conf new file mode 100644 index 000000000..cfa847144 --- /dev/null +++ b/maven-repository-webapp/src/main/resources/maven-proxy-complete.conf @@ -0,0 +1,145 @@ +################ GLOBAL SETTINGS +# This is where maven-proxy stores files it has downloaded +repo.local.store=/tmp/proxy-cache + +#The port to listen on - not used if loaded as a webapp +port=9999 + +#This is the base area that all files are loaded from. While it is possible to leave this blank, this behaviour +#is deprecated and will be disabled in version 2.0. There are too many namespace conflicts caused by not using +#a prefix. +#The repository will be shown at http://localhost:9999/repository/ +#for the .war loaded into a webapp server, the default prefix is "repository" (edit the web.xml to change) +# As maven doesn't like a trailing slash, this address shouldn't have one either. +prefix=repository + +#This is the simple date format used to display the last modified date while browsing the repository. +lastModifiedDateFormat=yyyy/MM/dd HH:mm:ss + +################ SNAPSHOT HANDLING +#If you want the proxy to look for newer snapshots, set to true +snapshot.update=true + +################ M2 METADATA HANDLING +#If you want the proxy to prevent looking for newer metadata, set to false (default is true) +#metadata.update=false + +################ M2 POM HANDLING +#If you want the proxy to look for newer POMs, set to true (default is false) +pom.update=true + +################ PROMOTION HANDLING +# ***** NOT CURRENTLY IMPLEMENTED ***** +#Promotion describes the process by which new artifacts are loaded to global maven-proxy repository. It +# is designed to be used by "higher security installations" that do not want to acquire artifacts from +# remote repositories without approval. +# +#If promotion handling is enabled, then the proxy will not download remote artifacts without permission +# (local repositories with copy=false are considered to be local) +# +#Permission to download is granted via the Promotion menu which will be enabled +# when promotion handling is enabled. +# +#If promotion is false, artifacts are sourced from any repository as per normal. +# +#Promotion and snapshots: If promotion is enabled, snapshots are not downloadable. The concept of using +# a snapshot in a production build (which is primarily what promotion is for) is counterintuitive. +## +promotion=false + +################ WEB INTERFACE +# This defines the absolute URL the server should use to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# The prefix will be added to this for the actual repository +# i.e. proxy available at http://localhost:9999/, repository at http://localhost:9999/repository +serverName=http://localhost:9999 + +#If true, the repository can be browsed +browsable=true + +#If true, the repository can be searched +searchable=true + +#Not currently implemented. Will allow webdav access to the repository at some point. +webdav=true + +#Stylesheet - if configured, will override the default stylesheet shipped with maven-proxy - absolute URLs only +#eg. /maven-proxy/style.css, http://www.example.com/style.css +stylesheet=/maven-proxy/style.css + +#bgColor / bgColorHighlight are replaced in the built in stylesheet to produce a simple color scheme. +#If a stylesheet is set, these are not used. +bgColor=#14B +bgColorHighlight=#94B + +#rowColor / rowColorHighlight are replaced in the built in stylesheet to produce a simple color scheme. +#If a stylesheet is set, these are not used. +rowColor=#CCF +rowColorHighlight=#DDF + + +################ PROXIES +#This is just a hack, it should auto discover them +#proxy.list=one,two,three +proxy.list= + +#Unauthenticated proxy +#proxy.one.host=proxy1.example.com +#proxy.one.port=3128 + +#Authenticated proxy +#proxy.two.host=proxy2.example.org +#proxy.two.port=80 +#proxy.two.username=username2 +#proxy.two.password=password2 + +#Authenticated proxy +#proxy.three.host=proxy3.example.net +#proxy.three.port=3129 +#proxy.three.username=username3 +#proxy.three.password=password3 + + +################# REPOSITORIES +#This is not just a hack, it specifies the order repositories should be checked +#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/" +repo.list=www-ibiblio-org + +#local-store +# The local store represents a location that local jars you host can be located. +# This could also be achieved by having a local http repository, but this is less cumbersome +repo.local-repo.url=file://target +repo.local-repo.description=Super Secret Custom Repository +#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos +repo.local-repo.copy=false +#If hardfail is true, any unexpected errors from the repository will cause +#the client download to fail (typically with a 500 error) +repo.local-repo.hardfail=true +#Don't cache a file repository +repo.local-repo.cache.period=0 + + +#www.ibiblio.org +repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2 +repo.www-ibiblio-org.description=www.ibiblio.org +repo.www-ibiblio-org.proxy= +repo.www-ibiblio-org.hardfail=true +#Cache this repository for 1 hour +repo.www-ibiblio-org.cache.period=3600 +repo.www-ibiblio-org.cache.failures=true + +#dist.codehaus.org +repo.dist-codehaus-org.url=http://dist.codehaus.org +repo.dist-codehaus-org.proxy=two +repo.dist-codehaus-org.hardfail=false +repo.dist-codehaus-org.cache.period=3600 +repo.dist-codehaus-org.cache.failures=true + +#private.example.com +repo.private-example-com.url=http://private.example.com/internal +repo.private-example-com.description=Commercial In Confidence Repository +repo.private-example-com.username=username1 +repo.private-example-com.password=password1 +repo.private-example-com.proxy=three +repo.private-example-com.cache.period=3600 diff --git a/maven-repository-webapp/src/main/resources/webwork.properties b/maven-repository-webapp/src/main/resources/webwork.properties new file mode 100644 index 000000000..138e918d1 --- /dev/null +++ b/maven-repository-webapp/src/main/resources/webwork.properties @@ -0,0 +1,3 @@ +# define our own action mapper here +webwork.mapper.class=org.apache.maven.repository.proxy.web.actionmapper.RepositoryProxyActionMapper +webwork.objectFactory = org.codehaus.plexus.xwork.PlexusObjectFactory diff --git a/maven-repository-webapp/src/main/resources/xwork.xml b/maven-repository-webapp/src/main/resources/xwork.xml index 24e2876e2..357f08abe 100644 --- a/maven-repository-webapp/src/main/resources/xwork.xml +++ b/maven-repository-webapp/src/main/resources/xwork.xml @@ -43,6 +43,16 @@ --> + + + application/octet-stream + artifactStream + 1024 + + notFoundError + proxyError + + /WEB-INF/jsp/generalresults.jsp /WEB-INF/jsp/index.jsp diff --git a/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/RepositoryProxyActionTest.java b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/RepositoryProxyActionTest.java new file mode 100644 index 000000000..a136d1d79 --- /dev/null +++ b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/RepositoryProxyActionTest.java @@ -0,0 +1,77 @@ +package org.apache.maven.repository.proxy.web.action.test; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.maven.repository.proxy.web.action.RepositoryProxyAction; +import org.apache.maven.repository.proxy.web.action.test.stub.ProxyManagerStub; +import org.codehaus.plexus.PlexusTestCase; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Properties; + +public class RepositoryProxyActionTest + extends PlexusTestCase +{ + + /** + * test basic proxy operation + * + * @throws Exception + */ + public void testProxy() + throws Exception + { + String testDir = getBasedir() + "/target/test-classes/unit/proxy-test"; + RepositoryProxyAction action = new RepositoryProxyAction(); + ProxyManagerStub proxyManager = new ProxyManagerStub( testDir ); + File cachedFile = proxyManager.get( "dummyFile" ); + + if ( !cachedFile.getParentFile().exists() ) + { + assertTrue( "can not create test file", cachedFile.getParentFile().mkdirs() ); + } + + if ( !cachedFile.exists() ) + { + assertTrue( "can not create test file", cachedFile.createNewFile() ); + } + + File tmpDir = getTestFile( "target/tmp-repo" ); + tmpDir.mkdirs(); + + // TODO: configure manually, test the property loader elsewhere + Properties properties = new Properties(); + properties.load( getClass().getResourceAsStream( "/unit/proxy-test/maven-proxy-complete.conf" ) ); + properties.setProperty( "repo.local.store", tmpDir.getAbsolutePath() ); + File tempFile = File.createTempFile( "test", "tmp" ); + tempFile.deleteOnExit(); + properties.store( new FileOutputStream( tempFile ), "" ); + + action.setConfigFile( tempFile.getAbsolutePath() ); + action.setProxyManager( proxyManager ); + + String result = action.execute(); + FileInputStream fileStream = action.getArtifactStream(); + + assertEquals( "proxy error", action.SUCCESS, result ); + assertNotNull( "inputstream not set", fileStream ); + assertNotNull( "cached file not set", action.getCachedFile() ); + assertTrue( "proxy error", cachedFile.getPath().equals( action.getCachedFile().getPath() ) ); + } +} diff --git a/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/HttpServletRequestStub.java b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/HttpServletRequestStub.java new file mode 100644 index 000000000..02c8fe5a7 --- /dev/null +++ b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/HttpServletRequestStub.java @@ -0,0 +1,154 @@ +package org.apache.maven.repository.proxy.web.action.test.stub; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.security.Principal; +import java.util.Enumeration; + +public class HttpServletRequestStub + extends ServletRequestStub + implements HttpServletRequest +{ + + public String getAuthType() + { + return null; + } + + public String getContextPath() + { + return "/location1/location2/location3"; + } + + public Cookie[] getCookies() + { + return null; + } + + public long getDateHeader( String name ) + { + return -1; + } + + public String getHeader( String name ) + { + return null; + } + + public Enumeration getHeaderNames() + { + return null; + } + + public Enumeration getHeaders( String name ) + { + return null; + } + + public int getIntHeader( String name ) + { + return -1; + } + + public String getMethod() + { + return null; + } + + public String getPathInfo() + { + return null; + } + + public String getPathTranslated() + { + return null; + } + + public String getQueryString() + { + return null; + } + + public String getRemoteUser() + { + return null; + } + + public String getRequestedSessionId() + { + return null; + } + + public String getRequestURI() + { + return "/projectname/repository/org/sometest/artifact-0.0.jar"; + } + + public StringBuffer getRequestURL() + { + return null; + } + + public String getServletPath() + { + return "/repository/org/sometest/artifact-0.0.jar"; + } + + public HttpSession getSession() + { + return null; + } + + public HttpSession getSession( boolean create ) + { + return null; + } + + public Principal getUserPrincipal() + { + return null; + } + + public boolean isRequestedSessionIdFromCookie() + { + return false; + } + + public boolean isRequestedSessionIdFromUrl() + { + return false; + } + + public boolean isRequestedSessionIdFromURL() + { + return false; + } + + public boolean isRequestedSessionIdValid() + { + return false; + } + + public boolean isUserInRole( String role ) + { + return false; + } +} diff --git a/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/ProxyManagerStub.java b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/ProxyManagerStub.java new file mode 100644 index 000000000..e7d3b21a5 --- /dev/null +++ b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/ProxyManagerStub.java @@ -0,0 +1,58 @@ +package org.apache.maven.repository.proxy.web.action.test.stub; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.maven.repository.proxy.ProxyManager; +import org.apache.maven.repository.proxy.configuration.ProxyConfiguration; + +import java.io.File; + +public class ProxyManagerStub + implements ProxyManager +{ + String baseDir; + + public ProxyManagerStub( String base ) + { + baseDir = base; + } + + public File get( String requestFile ) + { + return new File( baseDir, "proxy-cache/test-0.0.jar" ); + } + + public File getRemoteFile( String reqFile ) + { + return new File( baseDir, "proxy-chache/test-0.0.jar" ); + } + + public void setConfiguration( ProxyConfiguration config ) + { + // do nothing + } + + public ProxyConfiguration getConfiguration() + { + return null; + } + + public File getAlways( String name ) + { + return null; + } +} diff --git a/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/ServletRequestStub.java b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/ServletRequestStub.java new file mode 100644 index 000000000..e5919d19b --- /dev/null +++ b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/action/test/stub/ServletRequestStub.java @@ -0,0 +1,181 @@ +package org.apache.maven.repository.proxy.web.action.test.stub; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import java.io.BufferedReader; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public class ServletRequestStub + implements ServletRequest +{ + + public Object getAttribute( String key ) + { + return null; + } + + public Enumeration getAttributeNames() + { + return null; + } + + public String getCharacterEncoding() + { + return null; + } + + public int getContentLength() + { + return -1; + } + + public int getRemotePort() + { + return -1; + } + + public int getLocalPort() + { + return -1; + } + + public String getLocalAddr() + { + return null; + } + + public String getLocalName() + { + return null; + } + + public String getContentType() + { + return null; + } + + public ServletInputStream getInputStream() + { + return null; + } + + public Locale getLocale() + { + return null; + } + + public Enumeration getLocales() + { + return null; + } + + public String getParameter( String name ) + { + return null; + } + + public Map getParameterMap() + { + HashMap parameterMap = new HashMap(); + + parameterMap.put( "key1", "value1" ); + parameterMap.put( "key2", "value2" ); + + return parameterMap; + } + + public Enumeration getParameterNames() + { + return null; + } + + public String[] getParameterValues( String name ) + { + return null; + } + + public String getProtocol() + { + return null; + } + + public BufferedReader getReader() + { + return null; + } + + public String getRealPath( String path ) + { + return null; + } + + public String getRemoteAddr() + { + return null; + } + + public String getRemoteHost() + { + return null; + } + + public RequestDispatcher getRequestDispatcher( String path ) + { + return null; + } + + public String getScheme() + { + return null; + } + + public String getServerName() + { + return null; + } + + public int getServerPort() + { + return -1; + } + + public boolean isSecure() + { + return false; + } + + public void removeAttribute( String name ) + { + + } + + public void setAttribute( String name, Object value ) + { + + } + + public void setCharacterEncoding( String env ) + { + + } +} diff --git a/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/actionmapper/test/RepositoryProxyActionMapperTest.java b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/actionmapper/test/RepositoryProxyActionMapperTest.java new file mode 100644 index 000000000..4288a90fb --- /dev/null +++ b/maven-repository-webapp/src/test/java/org/apache/maven/repository/proxy/web/actionmapper/test/RepositoryProxyActionMapperTest.java @@ -0,0 +1,77 @@ +package org.apache.maven.repository.proxy.web.actionmapper.test; + +/* + * Copyright 2005-2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.opensymphony.webwork.dispatcher.mapper.ActionMapping; +import org.apache.maven.repository.proxy.web.action.test.stub.HttpServletRequestStub; +import org.apache.maven.repository.proxy.web.actionmapper.RepositoryProxyActionMapper; +import org.codehaus.plexus.PlexusTestCase; + +public class RepositoryProxyActionMapperTest + extends PlexusTestCase +{ + RepositoryProxyActionMapper actionMapper; + + public void setUp() + throws Exception + { + actionMapper = new RepositoryProxyActionMapper(); + } + + // TODO: uncomment once we know how to make the default action mapper work using stubs + // public void testDefaultActionMapping() + // throws Exception + // { + // ActionMapping mapping = actionMapper.getMapping( new DefaultActionMapperRequestStub() ); + // + // String expectedNamespace = "test"; + // String expectedName = "test"; + // + // assertNotNull( "ActionMapping is null", mapping ); + // assertNotNull( "namespace is null", mapping.getNamespace() ); + // assertNotNull( "name is null", mapping.getName() ); + // assertTrue( "invalid namespace: " + mapping.getNamespace(), mapping.getNamespace().equals( expectedNamespace ) ); + // assertTrue( "invalid name: " + mapping.getName(), mapping.getName().equals( expectedName ) ); + // } + + public void testRepositoryProxyActionMapping() + throws Exception + { + String testDir = getBasedir() + "/target/test-classes/unit/proxy-test"; + + actionMapper.setConfigfile( testDir + "/maven-proxy-complete.conf" ); + + ActionMapping mapping = actionMapper.getMapping( new HttpServletRequestStub() ); + String expectedName = "proxy"; + String expectedFile = "org/sometest/artifact-0.0.jar"; + + assertNotNull( "ActionMapping is null", mapping ); + assertNotNull( "name is null", mapping.getName() ); + + String mappingName = mapping.getName(); + String requestedFile = (String) mapping.getParams().get( "requestedFile" ); + + assertTrue( "invalid name: " + mappingName, mappingName.equals( expectedName ) ); + assertTrue( "invalid parameter: " + requestedFile, requestedFile.equals( expectedFile ) ); + } + + public void tearDown() + throws Exception + { + // do nothing + } +} diff --git a/maven-repository-webapp/src/test/resources/unit/proxy-test/maven-proxy-complete.conf b/maven-repository-webapp/src/test/resources/unit/proxy-test/maven-proxy-complete.conf new file mode 100644 index 000000000..95f01bb30 --- /dev/null +++ b/maven-repository-webapp/src/test/resources/unit/proxy-test/maven-proxy-complete.conf @@ -0,0 +1,145 @@ +################ GLOBAL SETTINGS +# This is where maven-proxy stores files it has downloaded +#repo.local.store=/tmp/proxy-cache + +#The port to listen on - not used if loaded as a webapp +port=9999 + +#This is the base area that all files are loaded from. While it is possible to leave this blank, this behaviour +#is deprecated and will be disabled in version 2.0. There are too many namespace conflicts caused by not using +#a prefix. +#The repository will be shown at http://localhost:9999/repository/ +#for the .war loaded into a webapp server, the default prefix is "repository" (edit the web.xml to change) +# As maven doesn't like a trailing slash, this address shouldn't have one either. +prefix=repository + +#This is the simple date format used to display the last modified date while browsing the repository. +lastModifiedDateFormat=yyyy/MM/dd HH:mm:ss + +################ SNAPSHOT HANDLING +#If you want the proxy to look for newer snapshots, set to true +snapshot.update=true + +################ M2 METADATA HANDLING +#If you want the proxy to prevent looking for newer metadata, set to false (default is true) +#metadata.update=false + +################ M2 POM HANDLING +#If you want the proxy to look for newer POMs, set to true (default is false) +pom.update=true + +################ PROMOTION HANDLING +# ***** NOT CURRENTLY IMPLEMENTED ***** +#Promotion describes the process by which new artifacts are loaded to global maven-proxy repository. It +# is designed to be used by "higher security installations" that do not want to acquire artifacts from +# remote repositories without approval. +# +#If promotion handling is enabled, then the proxy will not download remote artifacts without permission +# (local repositories with copy=false are considered to be local) +# +#Permission to download is granted via the Promotion menu which will be enabled +# when promotion handling is enabled. +# +#If promotion is false, artifacts are sourced from any repository as per normal. +# +#Promotion and snapshots: If promotion is enabled, snapshots are not downloadable. The concept of using +# a snapshot in a production build (which is primarily what promotion is for) is counterintuitive. +## +promotion=false + +################ WEB INTERFACE +# This defines the absolute URL the server should use to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# The prefix will be added to this for the actual repository +# i.e. proxy available at http://localhost:9999/, repository at http://localhost:9999/repository +serverName=http://localhost:9999 + +#If true, the repository can be browsed +browsable=true + +#If true, the repository can be searched +searchable=true + +#Not currently implemented. Will allow webdav access to the repository at some point. +webdav=true + +#Stylesheet - if configured, will override the default stylesheet shipped with maven-proxy - absolute URLs only +#eg. /maven-proxy/style.css, http://www.example.com/style.css +stylesheet=/maven-proxy/style.css + +#bgColor / bgColorHighlight are replaced in the built in stylesheet to produce a simple color scheme. +#If a stylesheet is set, these are not used. +bgColor=#14B +bgColorHighlight=#94B + +#rowColor / rowColorHighlight are replaced in the built in stylesheet to produce a simple color scheme. +#If a stylesheet is set, these are not used. +rowColor=#CCF +rowColorHighlight=#DDF + + +################ PROXIES +#This is just a hack, it should auto discover them +#proxy.list=one,two,three +proxy.list= + +#Unauthenticated proxy +#proxy.one.host=proxy1.example.com +#proxy.one.port=3128 + +#Authenticated proxy +#proxy.two.host=proxy2.example.org +#proxy.two.port=80 +#proxy.two.username=username2 +#proxy.two.password=password2 + +#Authenticated proxy +#proxy.three.host=proxy3.example.net +#proxy.three.port=3129 +#proxy.three.username=username3 +#proxy.three.password=password3 + + +################# REPOSITORIES +#This is not just a hack, it specifies the order repositories should be checked +#Note that the proxy adds a "/" which is why the urls aren't suffixed with a "/" +repo.list=www-ibiblio-org + +#local-store +# The local store represents a location that local jars you host can be located. +# This could also be achieved by having a local http repository, but this is less cumbersome +repo.local-repo.url=file://target +repo.local-repo.description=Super Secret Custom Repository +#If copy is true, jars are copied from the store to the proxy-repo. Only configurable for file:/// repos +repo.local-repo.copy=false +#If hardfail is true, any unexpected errors from the repository will cause +#the client download to fail (typically with a 500 error) +repo.local-repo.hardfail=true +#Don't cache a file repository +repo.local-repo.cache.period=0 + + +#www.ibiblio.org +repo.www-ibiblio-org.url=http://www.ibiblio.org/maven2 +repo.www-ibiblio-org.description=www.ibiblio.org +repo.www-ibiblio-org.proxy= +repo.www-ibiblio-org.hardfail=true +#Cache this repository for 1 hour +repo.www-ibiblio-org.cache.period=3600 +repo.www-ibiblio-org.cache.failures=true + +#dist.codehaus.org +repo.dist-codehaus-org.url=http://dist.codehaus.org +repo.dist-codehaus-org.proxy=two +repo.dist-codehaus-org.hardfail=false +repo.dist-codehaus-org.cache.period=3600 +repo.dist-codehaus-org.cache.failures=true + +#private.example.com +repo.private-example-com.url=http://private.example.com/internal +repo.private-example-com.description=Commercial In Confidence Repository +repo.private-example-com.username=username1 +repo.private-example-com.password=password1 +repo.private-example-com.proxy=three +repo.private-example-com.cache.period=3600 diff --git a/pom.xml b/pom.xml index abdc15c25..d5263e3c2 100644 --- a/pom.xml +++ b/pom.xml @@ -209,6 +209,11 @@ maven-repository-indexer ${pom.version} + + org.apache.maven.repository + maven-repository-proxy + ${pom.version} + org.apache.maven.repository maven-repository-utils