Starting refactoring of proxy handling.

This commit is contained in:
Martin Stockhammer 2019-01-31 22:49:06 +01:00
parent 847727d57d
commit 21220fcd57
189 changed files with 2200 additions and 1277 deletions

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>archiva-base</artifactId>
<groupId>org.apache.archiva</groupId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>archiva-maven2-common</artifactId>
<name>Archiva Base :: Maven2 Common</name>
<dependencies>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-proxy-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-file</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,4 +1,4 @@
package org.apache.archiva.proxy.common;
package org.apache.archiva.proxy.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -1,4 +1,4 @@
package org.apache.archiva.proxy.common;
package org.apache.archiva.proxy.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,4 +1,4 @@
package org.apache.archiva.proxy.common;
package org.apache.archiva.proxy.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,4 +1,4 @@
package org.apache.archiva.proxy.common;
package org.apache.archiva.proxy.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one

View File

@ -1,4 +1,4 @@
package org.apache.archiva.proxy.common;
package org.apache.archiva.proxy.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@ -18,7 +18,7 @@ package org.apache.archiva.proxy.common;
* under the License.
*/
import org.apache.archiva.admin.model.beans.NetworkProxy;
import org.apache.archiva.proxy.model.NetworkProxy;
import org.apache.commons.lang.StringUtils;
import java.util.HashMap;

View File

@ -48,7 +48,11 @@
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-proxy-common</artifactId>
<artifactId>archiva-proxy</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-maven2-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>

View File

@ -20,8 +20,6 @@ package org.apache.archiva.indexer.maven;
*/
import org.apache.archiva.admin.model.RepositoryAdminException;
import org.apache.archiva.admin.model.beans.NetworkProxy;
import org.apache.archiva.admin.model.networkproxy.NetworkProxyAdmin;
import org.apache.archiva.common.utils.FileUtils;
import org.apache.archiva.common.utils.PathUtil;
import org.apache.archiva.configuration.ArchivaConfiguration;
@ -30,9 +28,11 @@ import org.apache.archiva.indexer.ArchivaIndexingContext;
import org.apache.archiva.indexer.IndexCreationFailedException;
import org.apache.archiva.indexer.IndexUpdateFailedException;
import org.apache.archiva.indexer.UnsupportedBaseContextException;
import org.apache.archiva.proxy.common.WagonFactory;
import org.apache.archiva.proxy.common.WagonFactoryException;
import org.apache.archiva.proxy.common.WagonFactoryRequest;
import org.apache.archiva.proxy.ProxyRegistry;
import org.apache.archiva.proxy.maven.WagonFactory;
import org.apache.archiva.proxy.maven.WagonFactoryException;
import org.apache.archiva.proxy.maven.WagonFactoryRequest;
import org.apache.archiva.proxy.model.NetworkProxy;
import org.apache.archiva.repository.EditableRepository;
import org.apache.archiva.repository.ManagedRepository;
import org.apache.archiva.repository.PasswordCredentials;
@ -125,15 +125,15 @@ public class MavenIndexManager implements ArchivaIndexManager {
@Inject
private WagonFactory wagonFactory;
@Inject
private NetworkProxyAdmin networkProxyAdmin;
@Inject
private IndexUpdater indexUpdater;
@Inject
private ArtifactContextProducer artifactContextProducer;
@Inject
private ProxyRegistry proxyRegistry;
public static final String DEFAULT_INDEXER_DIR = ".indexer";
public static final String DEFAULT_PACKED_INDEX_DIR = ".index";
@ -291,14 +291,7 @@ public class MavenIndexManager implements ArchivaIndexManager {
RemoteIndexFeature rif = remoteRepository.getFeature( RemoteIndexFeature.class ).get( );
if ( StringUtils.isNotBlank( rif.getProxyId( ) ) )
{
try
{
networkProxy = networkProxyAdmin.getNetworkProxy( rif.getProxyId( ) );
}
catch ( RepositoryAdminException e )
{
log.error( "Error occured while retrieving proxy {}", e.getMessage( ) );
}
networkProxy = proxyRegistry.getNetworkProxy( rif.getProxyId( ) );
if ( networkProxy == null )
{
log.warn(

View File

@ -0,0 +1,192 @@
package org.apache.archiva.proxy.model;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 java.io.Serializable;
public class NetworkProxy
implements Serializable
{
private String id;
/**
* The network protocol to use with this proxy: "http", "socks-4"
* .
*/
private String protocol = "http";
/**
* The proxy host.
*/
private String host;
/**
* The proxy port.
*/
private int port = 8080;
/**
* The proxy user.
*/
private String username;
/**
* The proxy password.
*/
private String password;
/**
* @since 1.4-M3
*
* use NTLM proxy
*/
private boolean useNtlm;
public NetworkProxy()
{
// no op
}
public NetworkProxy( String id, String protocol, String host, int port, String username, String password )
{
this.id = id;
this.protocol = protocol;
this.host = host;
this.port = port;
this.username = username;
this.password = password;
}
public String getId()
{
return id;
}
public void setId( String id )
{
this.id = id;
}
public String getProtocol()
{
return protocol;
}
public void setProtocol( String protocol )
{
this.protocol = protocol;
}
public String getHost()
{
return host;
}
public void setHost( String host )
{
this.host = host;
}
public int getPort()
{
return port;
}
public void setPort( int port )
{
this.port = port;
}
public String getUsername()
{
return username;
}
public void setUsername( String username )
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword( String password )
{
this.password = password;
}
public boolean isUseNtlm()
{
return useNtlm;
}
public void setUseNtlm( boolean useNtlm )
{
this.useNtlm = useNtlm;
}
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
NetworkProxy that = (NetworkProxy) o;
if ( id != null ? !id.equals( that.id ) : that.id != null )
{
return false;
}
return true;
}
@Override
public int hashCode()
{
int result = 629 + ( id != null ? id.hashCode() : 0 );
return result;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "NetworkProxy" );
sb.append( "{id='" ).append( id ).append( '\'' );
sb.append( ", protocol='" ).append( protocol ).append( '\'' );
sb.append( ", host='" ).append( host ).append( '\'' );
sb.append( ", port=" ).append( port );
sb.append( ", username='" ).append( username ).append( '\'' );
//sb.append( ", password='" ).append( password ).append( '\'' );
sb.append( ", useNtlm=" ).append( useNtlm );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -49,6 +49,8 @@ public class ProxyConnector
private boolean disabled;
private Map<String, String> properties;
public ProxyConnector()
{
// no op
@ -167,4 +169,13 @@ public class ProxyConnector
{
this.order = order;
}
public Map<String, String> getProperties() {
return properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
}

View File

@ -1,4 +1,4 @@
package org.apache.archiva.admin.model.beans;
package org.apache.archiva.proxy.model;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file

View File

@ -22,17 +22,22 @@ package org.apache.archiva.proxy.model;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.policies.ProxyDownloadException;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryType;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
/**
* Handler for potential repository proxy connectors.
*
*
*/
public interface RepositoryProxyConnectors
public interface RepositoryProxyHandler
{
List<RepositoryType> supports();
/**
* Performs the artifact fetch operation against the target repositories
* of the provided source repository.
@ -88,4 +93,12 @@ public interface RepositoryProxyConnectors
* repository as a source repository.
*/
boolean hasProxies( ManagedRepositoryContent repository );
void setNetworkProxies(Map<String, NetworkProxy> proxies);
Map<String, NetworkProxy> getNetworkProxies();
NetworkProxy getNetworkProxy(String id);
}

View File

@ -24,14 +24,18 @@
<groupId>org.apache.archiva</groupId>
<version>3.0.0-SNAPSHOT</version>
</parent>
<artifactId>archiva-proxy-common</artifactId>
<name>Archiva Base :: Proxy Common</name>
<artifactId>archiva-proxy-maven</artifactId>
<name>Archiva Base :: Proxy Maven</name>
<properties>
<site.staging.base>${project.parent.parent.basedir}</site.staging.base>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-maven2-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-plexus-bridge</artifactId>
@ -44,6 +48,10 @@
<groupId>org.apache.maven.archetype</groupId>
<artifactId>archetype-common</artifactId>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-proxy</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-provider-api</artifactId>
@ -75,6 +83,13 @@
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</dependency>
<!--
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>maven2-repository</artifactId>
<scope>test</scope>
</dependency>
-->
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-test-utils</artifactId>
@ -86,5 +101,64 @@
<artifactId>asm</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva.redback.components.registry</groupId>
<artifactId>spring-registry-commons</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-test-utils</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva</groupId>
<artifactId>archiva-mock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva.redback</groupId>
<artifactId>redback-rbac-cached</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.archiva.redback</groupId>
<artifactId>redback-common-test-resources</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,427 @@
package org.apache.archiva.proxy.maven;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.archiva.configuration.NetworkProxyConfiguration;
import org.apache.archiva.model.RepositoryURL;
import org.apache.archiva.proxy.DefaultRepositoryProxyHandler;
import org.apache.archiva.proxy.NotFoundException;
import org.apache.archiva.proxy.NotModifiedException;
import org.apache.archiva.proxy.ProxyException;
import org.apache.archiva.proxy.model.NetworkProxy;
import org.apache.archiva.proxy.model.ProxyConnector;
import org.apache.archiva.repository.*;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.WagonException;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* DefaultRepositoryProxyHandler
* TODO exception handling needs work - "not modified" is not really an exceptional case, and it has more layers than
* your average brown onion
*/
@Service("repositoryProxyConnectors#maven")
public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
private static final List<RepositoryType> REPOSITORY_TYPES = new ArrayList<>();
static {
REPOSITORY_TYPES.add(RepositoryType.MAVEN);
}
@Inject
private WagonFactory wagonFactory;
private ConcurrentMap<String, ProxyInfo> networkProxyMap = new ConcurrentHashMap<>();
@Override
public void initialize() {
super.initialize();
}
private void updateWagonProxyInfo(Map<String, NetworkProxy> proxyList) {
this.networkProxyMap.clear();
List<NetworkProxyConfiguration> networkProxies = getArchivaConfiguration().getConfiguration().getNetworkProxies();
for ( Map.Entry<String, NetworkProxy> proxyEntry: proxyList.entrySet() )
{
String key = proxyEntry.getKey();
NetworkProxy networkProxyDef = proxyEntry.getValue();
ProxyInfo proxy = new ProxyInfo();
proxy.setType( networkProxyDef.getProtocol() );
proxy.setHost( networkProxyDef.getHost() );
proxy.setPort( networkProxyDef.getPort() );
proxy.setUserName( networkProxyDef.getUsername() );
proxy.setPassword( networkProxyDef.getPassword() );
this.networkProxyMap.put( key, proxy );
}
}
@Override
public void setNetworkProxies(Map<String, NetworkProxy> proxies) {
super.setNetworkProxies(proxies);
updateWagonProxyInfo(proxies);
}
/**
* @param connector
* @param remoteRepository
* @param tmpMd5
* @param tmpSha1
* @param tmpResource
* @param url
* @param remotePath
* @param resource
* @param workingDirectory
* @param repository
* @throws ProxyException
* @throws NotModifiedException
*
*/
protected void transferResources( ProxyConnector connector, RemoteRepositoryContent remoteRepository, Path tmpMd5,
Path tmpSha1, Path tmpResource, String url, String remotePath, Path resource,
Path workingDirectory, ManagedRepositoryContent repository )
throws ProxyException, NotModifiedException
{
Wagon wagon = null;
try
{
RepositoryURL repoUrl = remoteRepository.getURL();
String protocol = repoUrl.getProtocol();
NetworkProxy networkProxy = null;
String proxyId = connector.getProxyId();
if ( StringUtils.isNotBlank( proxyId ) )
{
networkProxy = getNetworkProxy( proxyId );
}
if (networkProxy==null) {
throw new ProxyException("No network proxy configurations found for id "+proxyId);
}
WagonFactoryRequest wagonFactoryRequest = new WagonFactoryRequest( "wagon#" + protocol,
remoteRepository.getRepository().getExtraHeaders() ).networkProxy(
networkProxy );
wagon = wagonFactory.getWagon( wagonFactoryRequest );
if ( wagon == null )
{
throw new ProxyException( "Unsupported target repository protocol: " + protocol );
}
if ( wagon == null )
{
throw new ProxyException( "Unsupported target repository protocol: " + protocol );
}
boolean connected = connectToRepository( connector, wagon, remoteRepository );
if ( connected )
{
transferArtifact( wagon, remoteRepository, remotePath, repository, resource, workingDirectory,
tmpResource );
// TODO: these should be used to validate the download based on the policies, not always downloaded
// to
// save on connections since md5 is rarely used
transferChecksum( wagon, remoteRepository, remotePath, repository, resource, workingDirectory, ".sha1",
tmpSha1 );
transferChecksum( wagon, remoteRepository, remotePath, repository, resource, workingDirectory, ".md5",
tmpMd5 );
}
}
catch ( NotFoundException e )
{
urlFailureCache.cacheFailure( url );
throw e;
}
catch ( NotModifiedException e )
{
// Do not cache url here.
throw e;
}
catch ( ProxyException e )
{
urlFailureCache.cacheFailure( url );
throw e;
}
catch ( WagonFactoryException e )
{
throw new ProxyException( e.getMessage(), e );
}
finally
{
if ( wagon != null )
{
try
{
wagon.disconnect();
}
catch ( ConnectionException e )
{
log.warn( "Unable to disconnect wagon.", e );
}
}
}
}
protected void transferArtifact( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
ManagedRepositoryContent repository, Path resource, Path tmpDirectory,
Path destFile )
throws ProxyException
{
transferSimpleFile( wagon, remoteRepository, remotePath, repository, resource, destFile );
}
/**
* <p>
* Quietly transfer the checksum file from the remote repository to the local file.
* </p>
*
* @param wagon the wagon instance (should already be connected) to use.
* @param remoteRepository the remote repository to transfer from.
* @param remotePath the remote path to the resource to get.
* @param repository the managed repository that will hold the file
* @param resource the local file that should contain the downloaded contents
* @param tmpDirectory the temporary directory to download to
* @param ext the type of checksum to transfer (example: ".md5" or ".sha1")
* @throws ProxyException if copying the downloaded file into place did not succeed.
*/
protected void transferChecksum( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
ManagedRepositoryContent repository, Path resource, Path tmpDirectory, String ext,
Path destFile )
throws ProxyException
{
String url = remoteRepository.getURL().getUrl() + remotePath + ext;
// Transfer checksum does not use the policy.
if ( urlFailureCache.hasFailedBefore( url ) )
{
return;
}
try
{
transferSimpleFile( wagon, remoteRepository, remotePath + ext, repository, resource, destFile );
log.debug( "Checksum {} Downloaded: {} to move to {}", url, destFile, resource );
}
catch ( NotFoundException e )
{
urlFailureCache.cacheFailure( url );
log.debug( "Transfer failed, checksum not found: {}", url );
// Consume it, do not pass this on.
}
catch ( NotModifiedException e )
{
log.debug( "Transfer skipped, checksum not modified: {}", url );
// Consume it, do not pass this on.
}
catch ( ProxyException e )
{
urlFailureCache.cacheFailure( url );
log.warn( "Transfer failed on checksum: {} : {}", url, e.getMessage(), e );
// Critical issue, pass it on.
throw e;
}
}
/**
* Perform the transfer of the remote file to the local file specified.
*
* @param wagon the wagon instance to use.
* @param remoteRepository the remote repository to use
* @param remotePath the remote path to attempt to get
* @param repository the managed repository that will hold the file
* @param origFile the local file to save to
* @throws ProxyException if there was a problem moving the downloaded file into place.
*/
protected void transferSimpleFile( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
ManagedRepositoryContent repository, Path origFile, Path destFile )
throws ProxyException
{
assert ( remotePath != null );
// Transfer the file.
try
{
boolean success = false;
if ( !Files.exists(origFile))
{
log.debug( "Retrieving {} from {}", remotePath, remoteRepository.getRepository().getName() );
wagon.get( addParameters( remotePath, remoteRepository.getRepository() ), destFile.toFile() );
success = true;
// You wouldn't get here on failure, a WagonException would have been thrown.
log.debug( "Downloaded successfully." );
}
else
{
log.debug( "Retrieving {} from {} if updated", remotePath, remoteRepository.getRepository().getName() );
try
{
success = wagon.getIfNewer( addParameters( remotePath, remoteRepository.getRepository() ), destFile.toFile(),
Files.getLastModifiedTime(origFile).toMillis());
}
catch ( IOException e )
{
throw new ProxyException( "Failed to the modification time of "+origFile.toAbsolutePath() );
}
if ( !success )
{
throw new NotModifiedException(
"Not downloaded, as local file is newer than remote side: " + origFile.toAbsolutePath() );
}
if ( Files.exists(destFile))
{
log.debug( "Downloaded successfully." );
}
}
}
catch ( ResourceDoesNotExistException e )
{
throw new NotFoundException(
"Resource [" + remoteRepository.getURL() + "/" + remotePath + "] does not exist: " + e.getMessage(),
e );
}
catch ( WagonException e )
{
// TODO: shouldn't have to drill into the cause, but TransferFailedException is often not descriptive enough
String msg =
"Download failure on resource [" + remoteRepository.getURL() + "/" + remotePath + "]:" + e.getMessage();
if ( e.getCause() != null )
{
msg += " (cause: " + e.getCause() + ")";
}
throw new ProxyException( msg, e );
}
}
/**
* Using wagon, connect to the remote repository.
*
* @param connector the connector configuration to utilize (for obtaining network proxy configuration from)
* @param wagon the wagon instance to establish the connection on.
* @param remoteRepository the remote repository to connect to.
* @return true if the connection was successful. false if not connected.
*/
protected boolean connectToRepository( ProxyConnector connector, Wagon wagon,
RemoteRepositoryContent remoteRepository )
{
boolean connected = false;
final ProxyInfo networkProxy =
connector.getProxyId() == null ? null : this.networkProxyMap.get( connector.getProxyId() );
if ( log.isDebugEnabled() )
{
if ( networkProxy != null )
{
// TODO: move to proxyInfo.toString()
String msg = "Using network proxy " + networkProxy.getHost() + ":" + networkProxy.getPort()
+ " to connect to remote repository " + remoteRepository.getURL();
if ( networkProxy.getNonProxyHosts() != null )
{
msg += "; excluding hosts: " + networkProxy.getNonProxyHosts();
}
if ( StringUtils.isNotBlank( networkProxy.getUserName() ) )
{
msg += "; as user: " + networkProxy.getUserName();
}
log.debug( msg );
}
}
AuthenticationInfo authInfo = null;
String username = "";
String password = "";
RepositoryCredentials repCred = remoteRepository.getRepository().getLoginCredentials();
if (repCred!=null && repCred instanceof PasswordCredentials) {
PasswordCredentials pwdCred = (PasswordCredentials) repCred;
username = pwdCred.getUsername();
password = pwdCred.getPassword()==null ? "" : new String(pwdCred.getPassword());
}
if ( StringUtils.isNotBlank( username ) && StringUtils.isNotBlank( password ) )
{
log.debug( "Using username {} to connect to remote repository {}", username, remoteRepository.getURL() );
authInfo = new AuthenticationInfo();
authInfo.setUserName( username );
authInfo.setPassword( password );
}
// Convert seconds to milliseconds
long timeoutInMilliseconds = remoteRepository.getRepository().getTimeout().toMillis();
// Set timeout read and connect
// FIXME olamy having 2 config values
wagon.setReadTimeout( (int) timeoutInMilliseconds );
wagon.setTimeout( (int) timeoutInMilliseconds );
try
{
Repository wagonRepository =
new Repository( remoteRepository.getId(), remoteRepository.getURL().toString() );
wagon.connect( wagonRepository, authInfo, networkProxy );
connected = true;
}
catch ( ConnectionException | AuthenticationException e )
{
log.warn( "Could not connect to {}: {}", remoteRepository.getRepository().getName(), e.getMessage() );
connected = false;
}
return connected;
}
public WagonFactory getWagonFactory()
{
return wagonFactory;
}
public void setWagonFactory( WagonFactory wagonFactory )
{
this.wagonFactory = wagonFactory;
}
@Override
public List<RepositoryType> supports() {
return REPOSITORY_TYPES;
}
}

View File

@ -20,8 +20,6 @@ package org.apache.archiva.proxy;
*/
import net.sf.ehcache.CacheManager;
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
import org.apache.archiva.admin.repository.managed.DefaultManagedRepositoryAdmin;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.configuration.ProxyConnectorConfiguration;
@ -32,11 +30,8 @@ import org.apache.archiva.policies.PropagateErrorsDownloadPolicy;
import org.apache.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy;
import org.apache.archiva.policies.ReleasesPolicy;
import org.apache.archiva.policies.SnapshotsPolicy;
import org.apache.archiva.proxy.model.RepositoryProxyConnectors;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryContentProvider;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.maven2.MavenManagedRepository;
import org.apache.archiva.proxy.model.RepositoryProxyHandler;
import org.apache.archiva.repository.*;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.maven.wagon.Wagon;
import org.easymock.EasyMock;
@ -52,7 +47,6 @@ import javax.inject.Inject;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
@ -110,7 +104,7 @@ public abstract class AbstractProxyTestCase
protected Wagon wagonMock;
protected RepositoryProxyConnectors proxyHandler;
protected RepositoryProxyHandler proxyHandler;
protected ManagedRepositoryContent managedDefaultRepository;
@ -142,10 +136,7 @@ public abstract class AbstractProxyTestCase
managedDefaultDir = Paths.get( managedDefaultRepository.getRepoRoot() );
org.apache.archiva.repository.ManagedRepository repoConfig = managedDefaultRepository.getRepository();
( (DefaultManagedRepositoryAdmin) applicationContext.getBean(
ManagedRepositoryAdmin.class ) ).setArchivaConfiguration( config );
org.apache.archiva.repository.ManagedRepository repoConfig = repositoryRegistry.getManagedRepository(ID_DEFAULT_MANAGED);
applicationContext.getBean( RepositoryRegistry.class ).putRepository( repoConfig );
@ -172,9 +163,9 @@ public abstract class AbstractProxyTestCase
// Setup the proxy handler.
//proxyHandler = applicationContext.getBean (RepositoryProxyConnectors) lookup( RepositoryProxyConnectors.class.getName() );
//proxyHandler = applicationContext.getBean (RepositoryProxyHandler) lookup( RepositoryProxyHandler.class.getName() );
proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyConnectors.class );
proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyHandler.class );
// Setup the wagon mock.
@ -328,14 +319,9 @@ public abstract class AbstractProxyTestCase
protected ManagedRepositoryContent createRepository( String id, String name, String path, String layout )
throws Exception
{
MavenManagedRepository repo = new MavenManagedRepository(id, name, Paths.get(path).getParent());
repo.setLocation( new URI(path) );
repo.setLayout( layout );
RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class );
ManagedRepositoryContent repoContent =
provider.createManagedContent( repo );
return repoContent;
ManagedRepository repo = new BasicManagedRepository(id, name, Paths.get(path));
repositoryRegistry.putRepository(repo);
return repositoryRegistry.getManagedRepository(id).getContent();
}
/**

View File

@ -19,8 +19,6 @@ package org.apache.archiva.proxy;
* under the License.
*/
import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
import org.apache.archiva.admin.repository.managed.DefaultManagedRepositoryAdmin;
import org.apache.archiva.configuration.ArchivaConfiguration;
import org.apache.archiva.configuration.NetworkProxyConfiguration;
import org.apache.archiva.configuration.ProxyConnectorConfiguration;
@ -32,11 +30,8 @@ import org.apache.archiva.policies.PropagateErrorsDownloadPolicy;
import org.apache.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy;
import org.apache.archiva.policies.ReleasesPolicy;
import org.apache.archiva.policies.SnapshotsPolicy;
import org.apache.archiva.proxy.model.RepositoryProxyConnectors;
import org.apache.archiva.repository.ManagedRepositoryContent;
import org.apache.archiva.repository.RepositoryContentProvider;
import org.apache.archiva.repository.RepositoryRegistry;
import org.apache.archiva.repository.maven2.MavenManagedRepository;
import org.apache.archiva.proxy.model.RepositoryProxyHandler;
import org.apache.archiva.repository.*;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.commons.io.FileUtils;
import org.assertj.core.api.Assertions;
@ -58,7 +53,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
@ -83,7 +77,7 @@ public class HttpProxyTransferTest
private static final String PROXIED_BASEDIR = "src/test/repositories/proxied1";
private RepositoryProxyConnectors proxyHandler;
private RepositoryProxyHandler proxyHandler;
private ArchivaConfiguration config;
@ -92,13 +86,24 @@ public class HttpProxyTransferTest
@Inject
private ApplicationContext applicationContext;
@Inject
private RepositoryRegistry repositoryRegistry;
private Server server;
protected ManagedRepositoryContent createRepository( String id, String name, String path, String layout )
throws Exception
{
ManagedRepository repo = new BasicManagedRepository(id, name, Paths.get(path));
repositoryRegistry.putRepository(repo);
return repositoryRegistry.getManagedRepository(id).getContent();
}
@Before
public void setUp()
throws Exception
{
proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyConnectors.class );
proxyHandler = applicationContext.getBean( "repositoryProxyConnectors#test", RepositoryProxyHandler.class );
config = applicationContext.getBean( "archivaConfiguration#mock", ArchivaConfiguration.class );
@ -120,26 +125,7 @@ public class HttpProxyTransferTest
// Make the destination dir.
Files.createDirectories(destRepoDir);
MavenManagedRepository repo = new MavenManagedRepository( MANAGED_ID, "Default Managed Repository", Paths.get(repoPath).getParent() );
repo.setLocation( new URI(repoPath) );
repo.setLayout( "default" );
RepositoryContentProvider provider = applicationContext.getBean( "repositoryContentProvider#maven", RepositoryContentProvider.class );
ManagedRepositoryContent repoContent =
provider.createManagedContent( repo );
managedDefaultRepository = repoContent;
( (DefaultManagedRepositoryAdmin) applicationContext.getBean(
ManagedRepositoryAdmin.class ) ).setArchivaConfiguration( config );
RepositoryRegistry managedRepositoryAdmin = applicationContext.getBean( RepositoryRegistry.class );
if ( managedRepositoryAdmin.getManagedRepository( repo.getId() ) == null )
{
managedRepositoryAdmin.putRepository( repo );
}
//config.getConfiguration().addManagedRepository( repo );
managedDefaultRepository = createRepository(MANAGED_ID, "Default Managed Repository", repoPath, "default");
Handler handler = new AbstractHandler()
{

View File

@ -20,6 +20,8 @@ package org.apache.archiva.proxy.common;
*/
import junit.framework.TestCase;
import org.apache.archiva.proxy.maven.WagonFactory;
import org.apache.archiva.proxy.maven.WagonFactoryRequest;
import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
import org.apache.maven.wagon.Wagon;
import org.junit.Test;
@ -29,7 +31,7 @@ import org.springframework.test.context.ContextConfiguration;
import javax.inject.Inject;
/**
* Test the WagonFactory works through Spring to be bound into the RepositoryProxyConnectors implementation.
* Test the WagonFactory works through Spring to be bound into the RepositoryProxyHandler implementation.
*/
@RunWith ( ArchivaSpringJUnit4ClassRunner.class )
@ContextConfiguration ( locations = { "classpath*:/META-INF/spring-context.xml" } )
@ -45,9 +47,9 @@ public class WagonFactoryTest
throws Exception
{
Wagon first = factory.getWagon( new WagonFactoryRequest().protocol( "wagon#file" ) );
Wagon first = factory.getWagon( new org.apache.archiva.proxy.maven.WagonFactoryRequest().protocol( "wagon#file" ) );
Wagon second = factory.getWagon( new WagonFactoryRequest().protocol( "wagon#file" ) );
Wagon second = factory.getWagon( new org.apache.archiva.proxy.maven.WagonFactoryRequest().protocol( "wagon#file" ) );
// ensure we support only protocol name too
Wagon third = factory.getWagon( new WagonFactoryRequest().protocol( "file" ) );

View File

@ -0,0 +1,90 @@
package org.apache.archiva.repository.mock;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.archiva.indexer.ArchivaIndexManager;
import org.apache.archiva.indexer.ArchivaIndexingContext;
import org.apache.archiva.indexer.IndexCreationFailedException;
import org.apache.archiva.indexer.IndexUpdateFailedException;
import org.apache.archiva.repository.Repository;
import org.apache.archiva.repository.RepositoryType;
import org.springframework.stereotype.Service;
import java.net.URI;
import java.util.Collection;
/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
@Service("archivaIndexManager#maven")
public class ArchivaIndexManagerMock implements ArchivaIndexManager {
@Override
public void pack(ArchivaIndexingContext context) throws IndexUpdateFailedException {
}
@Override
public void scan(ArchivaIndexingContext context) throws IndexUpdateFailedException {
}
@Override
public void update(ArchivaIndexingContext context, boolean fullUpdate) throws IndexUpdateFailedException {
}
@Override
public void addArtifactsToIndex(ArchivaIndexingContext context, Collection<URI> artifactReference) throws IndexUpdateFailedException {
}
@Override
public void removeArtifactsFromIndex(ArchivaIndexingContext context, Collection<URI> artifactReference) throws IndexUpdateFailedException {
}
@Override
public boolean supportsRepository(RepositoryType type) {
return true;
}
@Override
public ArchivaIndexingContext createContext(Repository repository) throws IndexCreationFailedException {
return null;
}
@Override
public ArchivaIndexingContext reset(ArchivaIndexingContext context) throws IndexUpdateFailedException {
return null;
}
@Override
public ArchivaIndexingContext move(ArchivaIndexingContext context, Repository repo) throws IndexCreationFailedException {
return null;
}
@Override
public void updateLocalIndexPath(Repository repo) {
}
}

View File

@ -0,0 +1,166 @@
package org.apache.archiva.repository.mock;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.archiva.model.ArchivaArtifact;
import org.apache.archiva.model.ArtifactReference;
import org.apache.archiva.model.ProjectReference;
import org.apache.archiva.model.VersionedReference;
import org.apache.archiva.repository.*;
import org.springframework.stereotype.Service;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Set;
/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
@Service("managedRepositoryContent#mock")
public class ManagedRepositoryContentMock implements ManagedRepositoryContent
{
private ManagedRepository repository;
@Override
public void deleteVersion( VersionedReference reference ) throws ContentNotFoundException
{
}
@Override
public void deleteArtifact( ArtifactReference artifactReference ) throws ContentNotFoundException
{
}
@Override
public void deleteGroupId( String groupId ) throws ContentNotFoundException
{
}
@Override
public void deleteProject( String namespace, String projectId ) throws RepositoryException
{
}
@Override
public String getId( )
{
return null;
}
@Override
public Set<ArtifactReference> getRelatedArtifacts( ArtifactReference reference ) throws ContentNotFoundException
{
return null;
}
@Override
public String getRepoRoot( )
{
return Paths.get("", "target", "test-repository", "managed").toString();
}
@Override
public ManagedRepository getRepository( )
{
return repository;
}
@Override
public Set<String> getVersions( ProjectReference reference ) throws ContentNotFoundException, LayoutException
{
return null;
}
@Override
public Set<String> getVersions( VersionedReference reference ) throws ContentNotFoundException
{
return null;
}
@Override
public boolean hasContent( ArtifactReference reference )
{
return false;
}
@Override
public boolean hasContent( ProjectReference reference )
{
return false;
}
@Override
public boolean hasContent( VersionedReference reference )
{
return false;
}
@Override
public void setRepository( ManagedRepository repo )
{
this.repository = repo;
}
@Override
public ArtifactReference toArtifactReference( String path ) throws LayoutException
{
return null;
}
@Override
public Path toFile( ArtifactReference reference )
{
return null;
}
@Override
public Path toFile( ArchivaArtifact reference )
{
return null;
}
@Override
public String toMetadataPath( ProjectReference reference )
{
return null;
}
@Override
public String toMetadataPath( VersionedReference reference )
{
return null;
}
@Override
public String toPath( ArtifactReference reference )
{
return null;
}
@Override
public String toPath( ArchivaArtifact reference )
{
return null;
}
}

View File

@ -0,0 +1,78 @@
package org.apache.archiva.repository.mock;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.archiva.model.ArtifactReference;
import org.apache.archiva.model.RepositoryURL;
import org.apache.archiva.repository.LayoutException;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RemoteRepositoryContent;
import org.springframework.stereotype.Service;
/**
* @author Martin Stockhammer <martin_s@apache.org>
*/
@Service("remoteRepositoryContent#mock")
public class RemoteRepositoryContentMock implements RemoteRepositoryContent
{
RemoteRepository repository;
@Override
public String getId( )
{
return null;
}
@Override
public RemoteRepository getRepository( )
{
return null;
}
@Override
public RepositoryURL getURL( )
{
return null;
}
@Override
public void setRepository( RemoteRepository repo )
{
this.repository = repo;
}
@Override
public ArtifactReference toArtifactReference( String path ) throws LayoutException
{
return null;
}
@Override
public String toPath( ArtifactReference reference )
{
return null;
}
@Override
public RepositoryURL toURL( ArtifactReference reference )
{
return null;
}
}

View File

@ -0,0 +1,66 @@
package org.apache.archiva.repository.mock;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.archiva.repository.*;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.Set;
@Service("repositoryContentProvider#mock")
public class RepositoryContentProviderMock implements RepositoryContentProvider {
private static final Set<RepositoryType> REPOSITORY_TYPES = new HashSet<>();
static {
REPOSITORY_TYPES.add(RepositoryType.MAVEN);
REPOSITORY_TYPES.add(RepositoryType.NPM);
}
@Override
public boolean supportsLayout(String layout) {
return true;
}
@Override
public Set<RepositoryType> getSupportedRepositoryTypes() {
return REPOSITORY_TYPES;
}
@Override
public boolean supports(RepositoryType type) {
return true;
}
@Override
public RemoteRepositoryContent createRemoteContent(RemoteRepository repository) throws RepositoryException {
return new RemoteRepositoryContentMock();
}
@Override
public ManagedRepositoryContent createManagedContent(ManagedRepository repository) throws RepositoryException {
return new ManagedRepositoryContentMock();
}
@Override
public <T extends RepositoryContent, V extends Repository> T createContent(Class<T> clazz, V repository) throws RepositoryException {
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More