123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970 |
- package org.apache.archiva.proxy;
-
- /*
- * 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.checksum.ChecksumAlgorithm;
- import org.apache.archiva.checksum.ChecksumUtil;
- import org.apache.archiva.common.filelock.FileLockManager;
- import org.apache.archiva.configuration.ArchivaConfiguration;
- import org.apache.archiva.configuration.ProxyConnectorConfiguration;
- import org.apache.archiva.configuration.ProxyConnectorRuleConfiguration;
- import org.apache.archiva.model.ArtifactReference;
- import org.apache.archiva.model.Keys;
- import org.apache.archiva.policies.DownloadErrorPolicy;
- import org.apache.archiva.policies.DownloadPolicy;
- import org.apache.archiva.policies.Policy;
- import org.apache.archiva.policies.PolicyConfigurationException;
- import org.apache.archiva.policies.PolicyOption;
- import org.apache.archiva.policies.PolicyViolationException;
- import org.apache.archiva.policies.PostDownloadPolicy;
- import org.apache.archiva.policies.PreDownloadPolicy;
- import org.apache.archiva.policies.ProxyDownloadException;
- import org.apache.archiva.policies.urlcache.UrlFailureCache;
- import org.apache.archiva.proxy.model.NetworkProxy;
- import org.apache.archiva.proxy.model.ProxyConnector;
- import org.apache.archiva.proxy.model.ProxyFetchResult;
- import org.apache.archiva.proxy.model.RepositoryProxyHandler;
- import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
- import org.apache.archiva.repository.ManagedRepository;
- import org.apache.archiva.repository.RemoteRepository;
- import org.apache.archiva.repository.RemoteRepositoryContent;
- import org.apache.archiva.repository.RepositoryType;
- import org.apache.archiva.repository.metadata.base.MetadataTools;
- import org.apache.archiva.repository.metadata.RepositoryMetadataException;
- import org.apache.archiva.repository.storage.FilesystemStorage;
- import org.apache.archiva.repository.storage.StorageAsset;
- import org.apache.archiva.repository.storage.StorageUtil;
- import org.apache.archiva.scheduler.ArchivaTaskScheduler;
- import org.apache.archiva.scheduler.repository.model.RepositoryTask;
- import org.apache.commons.collections4.CollectionUtils;
- import org.apache.commons.io.FilenameUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.commons.lang3.SystemUtils;
- import org.apache.tools.ant.types.selectors.SelectorUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.slf4j.MarkerFactory;
-
- import javax.annotation.PostConstruct;
- import javax.inject.Inject;
- import javax.inject.Named;
- import java.io.IOException;
- import java.net.MalformedURLException;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.StandardCopyOption;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentMap;
-
- public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
-
- protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
- @Inject
- protected UrlFailureCache urlFailureCache;
-
- @Inject
- @Named(value = "metadataTools#default")
- private MetadataTools metadataTools;
-
- private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>( );
- private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>( );
- private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>( );
- private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
-
- @Inject
- @Named(value = "archivaTaskScheduler#repository")
- private ArchivaTaskScheduler<RepositoryTask> scheduler;
-
- @Inject
- private ArchivaConfiguration archivaConfiguration;
-
- @Inject
- @Named(value = "fileLockManager#default")
- private FileLockManager fileLockManager;
-
- private Map<String, NetworkProxy> networkProxyMap = new ConcurrentHashMap<>();
- private List<ChecksumAlgorithm> checksumAlgorithms;
-
- @PostConstruct
- public void initialize()
- {
- checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
- }
-
- private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
- String targetRepository,
- List<ProxyConnectorRuleConfiguration> all )
- {
- List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations = new ArrayList<>();
-
- for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : all )
- {
- for ( ProxyConnectorConfiguration proxyConnector : proxyConnectorRuleConfiguration.getProxyConnectors() )
- {
- if ( StringUtils.equals( sourceRepository, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
- targetRepository, proxyConnector.getTargetRepoId() ) )
- {
- proxyConnectorRuleConfigurations.add( proxyConnectorRuleConfiguration );
- }
- }
- }
-
- return proxyConnectorRuleConfigurations;
- }
-
- @Override
- public StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
- throws ProxyDownloadException
- {
- StorageAsset localFile = toLocalFile( repository, artifact );
-
- Properties requestProperties = new Properties();
- requestProperties.setProperty( "filetype", "artifact" );
- requestProperties.setProperty( "version", artifact.getVersion() );
- requestProperties.setProperty( "managedRepositoryId", repository.getId() );
-
- List<ProxyConnector> connectors = getProxyConnectors( repository );
- Map<String, Exception> previousExceptions = new LinkedHashMap<>();
- for ( ProxyConnector connector : connectors )
- {
- if ( !connector.isEnabled() )
- {
- continue;
- }
-
- RemoteRepository targetRepository = connector.getTargetRepository();
- requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
-
- String targetPath = targetRepository.getContent().toPath( artifact );
-
- if ( SystemUtils.IS_OS_WINDOWS )
- {
- // toPath use system PATH_SEPARATOR so on windows url are \ which doesn't work very well :-)
- targetPath = FilenameUtils.separatorsToUnix( targetPath );
- }
-
- try
- {
- StorageAsset downloadedFile =
- transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
- true );
-
- if ( fileExists(downloadedFile) )
- {
- log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
- return downloadedFile;
- }
- }
- catch ( NotFoundException e )
- {
- log.debug( "Artifact {} not found on repository \"{}\".", Keys.toKey( artifact ),
- targetRepository.getId() );
- }
- catch ( NotModifiedException e )
- {
- log.debug( "Artifact {} not updated on repository \"{}\".", Keys.toKey( artifact ),
- targetRepository.getId() );
- }
- catch ( ProxyException e )
- {
- validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact,
- targetRepository.getContent(), localFile, e, previousExceptions );
- }
- }
-
- if ( !previousExceptions.isEmpty() )
- {
- throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
- previousExceptions );
- }
-
- log.debug( "Exhausted all target repositories, artifact {} not found.", Keys.toKey( artifact ) );
-
- return null;
- }
-
- @Override
- public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
- {
- StorageAsset localFile = repository.getAsset( path );
-
- // no update policies for these paths
- if ( localFile.exists() )
- {
- return null;
- }
-
- Properties requestProperties = new Properties();
- requestProperties.setProperty( "filetype", "resource" );
- requestProperties.setProperty( "managedRepositoryId", repository.getId() );
-
- List<ProxyConnector> connectors = getProxyConnectors( repository );
- for ( ProxyConnector connector : connectors )
- {
- if ( !connector.isEnabled() )
- {
- continue;
- }
-
- RemoteRepository targetRepository = connector.getTargetRepository();
- requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
-
- String targetPath = path;
-
- try
- {
- StorageAsset downloadedFile =
- transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
- false );
-
- if ( fileExists( downloadedFile ) )
- {
- log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
- return downloadedFile;
- }
- }
- catch ( NotFoundException e )
- {
- log.debug( "Resource {} not found on repository \"{}\".", path,
- targetRepository.getId() );
- }
- catch ( NotModifiedException e )
- {
- log.debug( "Resource {} not updated on repository \"{}\".", path,
- targetRepository.getId() );
- }
- catch ( ProxyException e )
- {
- log.warn(
- "Transfer error from repository {} for resource {}, continuing to next repository. Error message: {}",
- targetRepository.getId(), path, e.getMessage() );
- log.debug( MarkerFactory.getDetachedMarker( "transfer.error" ),
- "Transfer error from repository \"{}"
- + "\" for resource {}, continuing to next repository. Error message: {}",
- targetRepository.getId(), path, e.getMessage(), e );
- }
-
- }
-
- log.debug( "Exhausted all target repositories, resource {} not found.", path );
-
- return null;
- }
-
- @Override
- public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String logicalPath )
- {
- StorageAsset localFile = repository.getAsset( logicalPath );
-
- Properties requestProperties = new Properties();
- requestProperties.setProperty( "filetype", "metadata" );
- boolean metadataNeedsUpdating = false;
- long originalTimestamp = getLastModified( localFile );
-
- List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
- for ( ProxyConnector connector : connectors )
- {
- if ( !connector.isEnabled() )
- {
- continue;
- }
-
- RemoteRepository targetRepository = connector.getTargetRepository();
-
- StorageAsset localRepoFile = toLocalRepoFile( repository, targetRepository.getContent(), logicalPath );
- long originalMetadataTimestamp = getLastModified( localRepoFile );
-
- try
- {
- transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
- true );
-
- if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
- {
- metadataNeedsUpdating = true;
- }
- }
- catch ( NotFoundException e )
- {
-
- log.debug( "Metadata {} not found on remote repository '{}'.", logicalPath,
- targetRepository.getId(), e );
-
- }
- catch ( NotModifiedException e )
- {
-
- log.debug( "Metadata {} not updated on remote repository '{}'.", logicalPath,
- targetRepository.getId(), e );
-
- }
- catch ( ProxyException e )
- {
- log.warn(
- "Transfer error from repository {} for versioned Metadata {}, continuing to next repository. Error message: {}",
- targetRepository.getId(), logicalPath, e.getMessage() );
- log.debug( "Full stack trace", e );
- }
- }
-
- if ( hasBeenUpdated( localFile, originalTimestamp ) )
- {
- metadataNeedsUpdating = true;
- }
-
- if ( metadataNeedsUpdating || !localFile.exists())
- {
- try
- {
- metadataTools.updateMetadata( repository.getContent(), logicalPath );
- }
- catch ( RepositoryMetadataException e )
- {
- log.warn( "Unable to update metadata {}:{}", localFile.getPath(), e.getMessage(), e );
- }
-
- }
-
- if ( fileExists( localFile ) )
- {
- return new ProxyFetchResult( localFile, metadataNeedsUpdating );
- }
-
- return new ProxyFetchResult( null, false );
- }
-
- private long getLastModified(StorageAsset file )
- {
- if ( !file.exists() || file.isContainer() )
- {
- return 0;
- }
-
- return file.getModificationTime().toEpochMilli();
- }
-
- private boolean hasBeenUpdated(StorageAsset file, long originalLastModified )
- {
- if ( !file.exists() || file.isContainer() )
- {
- return false;
- }
-
- long currentLastModified = getLastModified( file );
- return ( currentLastModified > originalLastModified );
- }
-
- private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
- String targetPath )
- {
- String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
- return repository.getAsset( repoPath );
- }
-
- /**
- * Test if the provided ManagedRepositoryContent has any proxies configured for it.
- * @param repository
- */
- @Override
- public boolean hasProxies( ManagedRepository repository )
- {
- synchronized ( this.proxyConnectorMap )
- {
- return this.proxyConnectorMap.containsKey( repository.getId() );
- }
- }
-
- private StorageAsset toLocalFile(ManagedRepository repository, ArtifactReference artifact )
- {
- return repository.getContent().toFile( artifact );
- }
-
- /**
- * Simple method to test if the file exists on the local disk.
- *
- * @param file the file to test. (may be null)
- * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
- */
- private boolean fileExists( StorageAsset file )
- {
- if ( file == null )
- {
- return false;
- }
-
- if ( !file.exists())
- {
- return false;
- }
-
- return !file.isContainer();
- }
-
- /**
- * Perform the transfer of the file.
- *
- * @param connector the connector configuration to use.
- * @param remoteRepository the remote repository get the resource from.
- * @param remotePath the path in the remote repository to the resource to get.
- * @param repository the managed repository that will hold the file
- * @param resource the path relative to the repository storage where the file should be downloaded to
- * @param requestProperties the request properties to utilize for policy handling.
- * @param executeConsumers whether to execute the consumers after proxying
- * @return the local file that was downloaded, or null if not downloaded.
- * @throws NotFoundException if the file was not found on the remote repository.
- * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, but
- * the remote resource is not newer than the local File.
- * @throws ProxyException if transfer was unsuccessful.
- */
- protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
- ManagedRepository repository, StorageAsset resource, Properties requestProperties,
- boolean executeConsumers )
- throws ProxyException, NotModifiedException
- {
- String url = null;
- try
- {
- url = remoteRepository.getLocation().toURL().toString();
- }
- catch ( MalformedURLException e )
- {
- throw new ProxyException( e.getMessage(), e );
- }
- if ( !url.endsWith( "/" ) )
- {
- url = url + "/";
- }
- url = url + remotePath;
- requestProperties.setProperty( "url", url );
-
- // Is a whitelist defined?
- if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
- {
- // Path must belong to whitelist.
- if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
- {
- log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
- remotePath, remoteRepository.getId() );
- return null;
- }
- }
-
- // Is target path part of blacklist?
- if ( matchesPattern( remotePath, connector.getBlacklist() ) )
- {
- log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
- remoteRepository.getId() );
- return null;
- }
-
- // Handle pre-download policy
- try
- {
- validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, resource );
- }
- catch ( PolicyViolationException e )
- {
- String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
- if ( resource.exists() )
- {
- log.debug( "{} : using already present local file.", emsg );
- return resource;
- }
-
- log.debug( emsg );
- return null;
- }
-
- Path workingDirectory = createWorkingDirectory( repository );
- FilesystemStorage tmpStorage = null;
- try
- {
- tmpStorage = new FilesystemStorage( workingDirectory, fileLockManager );
- }
- catch ( IOException e )
- {
- throw new ProxyException( "Could not create tmp storage" );
- }
- StorageAsset tmpResource = tmpStorage.getAsset( resource.getName( ) );
- StorageAsset[] tmpChecksumFiles = new StorageAsset[checksumAlgorithms.size()];
- for(int i=0; i<checksumAlgorithms.size(); i++) {
- ChecksumAlgorithm alg = checksumAlgorithms.get( i );
- tmpChecksumFiles[i] = tmpStorage.getAsset( resource.getName() + "." + alg.getDefaultExtension() );
- }
-
- try
- {
-
- transferResources( connector, remoteRepository, tmpResource,tmpChecksumFiles , url, remotePath,
- resource, workingDirectory, repository );
-
- // Handle post-download policies.
- try
- {
- validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, tmpResource );
- }
- catch ( PolicyViolationException e )
- {
- log.warn( "Transfer invalidated from {} : {}", url, e.getMessage() );
- executeConsumers = false;
- if ( !fileExists( tmpResource ) )
- {
- resource = null;
- }
- }
-
- if ( resource != null )
- {
- synchronized ( resource.getPath().intern() )
- {
- StorageAsset directory = resource.getParent();
- for (int i=0; i<tmpChecksumFiles.length; i++) {
- moveFileIfExists( tmpChecksumFiles[i], directory );
- }
- moveFileIfExists( tmpResource, directory );
- }
- }
- }
- finally
- {
- org.apache.archiva.common.utils.FileUtils.deleteQuietly( workingDirectory );
- }
-
- if ( executeConsumers )
- {
- // Just-in-time update of the index and database by executing the consumers for this artifact
- //consumers.executeConsumers( connector.getSourceRepository().getRepository(), resource );
- queueRepositoryTask( connector.getSourceRepository().getId(), resource );
- }
-
- return resource;
- }
-
- protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
- StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
- ManagedRepository repository ) throws ProxyException;
-
- private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
- {
- RepositoryTask task = new RepositoryTask();
- task.setRepositoryId( repositoryId );
- task.setResourceFile( localFile );
- task.setUpdateRelatedArtifacts( true );
- task.setScanAll( true );
-
- try
- {
- scheduler.queueTask( task );
- }
- catch ( TaskQueueException e )
- {
- log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
- + "'].", localFile.getName() );
- }
- }
-
- /**
- * Moves the file into repository location if it exists
- *
- * @param fileToMove this could be either the main artifact, sha1 or md5 checksum file.
- * @param directory directory to write files to
- */
- private void moveFileIfExists( StorageAsset fileToMove, StorageAsset directory )
- throws ProxyException
- {
- if ( fileToMove != null && fileToMove.exists() )
- {
- StorageAsset newLocation = directory.getStorage().getAsset( directory.getPath()+ "/" + fileToMove.getName());
- moveTempToTarget( fileToMove, newLocation );
- }
- }
-
- /**
- * Apply the policies.
- *
- * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
- * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy
- * setting)
- * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)}
- * )
- * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
- * @throws PolicyViolationException
- */
- private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
- Properties request, StorageAsset localFile )
- throws PolicyViolationException
- {
- for ( Map.Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
- {
- // olamy with spring rolehint is now downloadPolicy#hint
- // so substring after last # to get the hint as with plexus
- String key = entry.getValue( ).getId( );
- DownloadPolicy policy = entry.getValue();
- PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
-
- log.debug( "Applying [{}] policy with [{}]", key, option );
- try
- {
- policy.applyPolicy( option, request, localFile );
- }
- catch ( PolicyConfigurationException e )
- {
- log.error( e.getMessage(), e );
- }
- }
- }
-
- private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
- Properties request, ArtifactReference artifact, RemoteRepositoryContent content,
- StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
- throws ProxyDownloadException
- {
- boolean process = true;
- for ( Map.Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() )
- {
-
- // olamy with spring rolehint is now downloadPolicy#hint
- // so substring after last # to get the hint as with plexus
- String key = entry.getValue( ).getId( );
- DownloadErrorPolicy policy = entry.getValue();
- PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
-
- log.debug( "Applying [{}] policy with [{}]", key, option );
- try
- {
- // all policies must approve the exception, any can cancel
- process = policy.applyPolicy( option, request, localFile, exception, previousExceptions );
- if ( !process )
- {
- break;
- }
- }
- catch ( PolicyConfigurationException e )
- {
- log.error( e.getMessage(), e );
- }
- }
-
- if ( process )
- {
- // if the exception was queued, don't throw it
- if ( !previousExceptions.containsKey( content.getId() ) )
- {
- throw new ProxyDownloadException(
- "An error occurred in downloading from the remote repository, and the policy is to fail immediately",
- content.getId(), exception );
- }
- }
- else
- {
- // if the exception was queued, but cancelled, remove it
- previousExceptions.remove( content.getId() );
- }
-
- log.warn(
- "Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
- content.getRepository().getId(), Keys.toKey( artifact ), exception.getMessage() );
- log.debug( "Full stack trace", exception );
- }
-
- /**
- * Creates a working directory
- *
- * @param repository
- * @return file location of working directory
- */
- private Path createWorkingDirectory( ManagedRepository repository )
- {
- try
- {
- return Files.createTempDirectory( "temp" );
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e.getMessage(), e );
- }
-
- }
-
- /**
- * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles its
- * downloaded files.
- *
- * @param temp The completed download file
- * @param target The final location of the downloaded file
- * @throws ProxyException when the temp file cannot replace the target file
- */
- private void moveTempToTarget( StorageAsset temp, StorageAsset target )
- throws ProxyException
- {
-
- try
- {
- StorageUtil.moveAsset( temp, target, true , StandardCopyOption.REPLACE_EXISTING);
- }
- catch ( IOException e )
- {
- log.error( "Move failed from {} to {}, trying copy.", temp, target );
- try
- {
- StorageUtil.copyAsset( temp, target, true );
- if (temp.exists()) {
- temp.getStorage( ).removeAsset( temp );
- }
- }
- catch ( IOException ex )
- {
- log.error("Copy failed from {} to {}: ({}) {}", temp, target, e.getClass(), e.getMessage());
- throw new ProxyException("Could not move temp file "+temp.getPath()+" to target "+target.getPath()+": ("+e.getClass()+") "+e.getMessage(), e);
- }
- }
- }
-
- /**
- * Tests whitelist and blacklist patterns against path.
- *
- * @param path the path to test.
- * @param patterns the list of patterns to check.
- * @return true if the path matches at least 1 pattern in the provided patterns list.
- */
- private boolean matchesPattern( String path, List<String> patterns )
- {
- if ( CollectionUtils.isEmpty( patterns ) )
- {
- return false;
- }
-
- if ( !path.startsWith( "/" ) )
- {
- path = "/" + path;
- }
-
- for ( String pattern : patterns )
- {
- if ( !pattern.startsWith( "/" ) )
- {
- pattern = "/" + pattern;
- }
-
- if ( SelectorUtils.matchPath( pattern, path, false ) )
- {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
- * @param repository
- */
- @Override
- public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
- {
-
- if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
- {
- return Collections.emptyList();
- }
- List<ProxyConnector> ret = new ArrayList<>( this.proxyConnectorMap.get( repository.getId() ) );
-
- Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
- return ret;
-
- }
-
-
- protected String addParameters(String path, RemoteRepository remoteRepository )
- {
- if ( remoteRepository.getExtraParameters().isEmpty() )
- {
- return path;
- }
-
- boolean question = false;
-
- StringBuilder res = new StringBuilder( path == null ? "" : path );
-
- for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters().entrySet() )
- {
- if ( !question )
- {
- res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() );
- }
- }
-
- return res.toString();
- }
-
- public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
- {
- this.archivaConfiguration = archivaConfiguration;
- }
-
- public MetadataTools getMetadataTools()
- {
- return metadataTools;
- }
-
- public void setMetadataTools(MetadataTools metadataTools )
- {
- this.metadataTools = metadataTools;
- }
-
- public UrlFailureCache getUrlFailureCache()
- {
- return urlFailureCache;
- }
-
- public void setUrlFailureCache(UrlFailureCache urlFailureCache )
- {
- this.urlFailureCache = urlFailureCache;
- }
-
- public Map<String, PreDownloadPolicy> getPreDownloadPolicies()
- {
- return preDownloadPolicies;
- }
-
- public void setPreDownloadPolicies(Map<String, PreDownloadPolicy> preDownloadPolicies )
- {
- this.preDownloadPolicies = preDownloadPolicies;
- }
-
- public Map<String, PostDownloadPolicy> getPostDownloadPolicies()
- {
- return postDownloadPolicies;
- }
-
- public void setPostDownloadPolicies(Map<String, PostDownloadPolicy> postDownloadPolicies )
- {
- this.postDownloadPolicies = postDownloadPolicies;
- }
-
- public Map<String, DownloadErrorPolicy> getDownloadErrorPolicies()
- {
- return downloadErrorPolicies;
- }
-
- public void setDownloadErrorPolicies(Map<String, DownloadErrorPolicy> downloadErrorPolicies )
- {
- this.downloadErrorPolicies = downloadErrorPolicies;
- }
-
- @Override
- public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
- this.networkProxyMap.clear();
- this.networkProxyMap.putAll( networkProxies );
- }
-
- @Override
- public NetworkProxy getNetworkProxy(String id) {
- return this.networkProxyMap.get(id);
- }
-
- @Override
- public Map<String, NetworkProxy> getNetworkProxies() {
- return this.networkProxyMap;
- }
-
- @Override
- public abstract List<RepositoryType> supports();
-
- @Override
- public void setPolicies( List<Policy> policyList )
- {
- preDownloadPolicies.clear();
- postDownloadPolicies.clear();
- downloadErrorPolicies.clear();
- for (Policy policy : policyList) {
- addPolicy( policy );
- }
- }
-
- void addPolicy(PreDownloadPolicy policy) {
- preDownloadPolicies.put( policy.getId( ), policy );
- }
-
- void addPolicy(PostDownloadPolicy policy) {
- postDownloadPolicies.put( policy.getId( ), policy );
- }
- void addPolicy(DownloadErrorPolicy policy) {
- downloadErrorPolicies.put( policy.getId( ), policy );
- }
-
- @Override
- public void addPolicy( Policy policy )
- {
- if (policy instanceof PreDownloadPolicy) {
- addPolicy( (PreDownloadPolicy)policy );
- } else if (policy instanceof PostDownloadPolicy) {
- addPolicy( (PostDownloadPolicy) policy );
- } else if (policy instanceof DownloadErrorPolicy) {
- addPolicy( (DownloadErrorPolicy) policy );
- } else {
- log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
- }
- }
-
- @Override
- public void removePolicy( Policy policy )
- {
- final String id = policy.getId();
- if (preDownloadPolicies.containsKey( id )) {
- preDownloadPolicies.remove( id );
- } else if (postDownloadPolicies.containsKey( id )) {
- postDownloadPolicies.remove( id );
- } else if (downloadErrorPolicies.containsKey( id )) {
- downloadErrorPolicies.remove( id );
- }
- }
-
- @Override
- public void addProxyConnector( ProxyConnector connector )
- {
- final String sourceId = connector.getSourceRepository( ).getId( );
- List<ProxyConnector> connectors;
- if (proxyConnectorMap.containsKey( sourceId )) {
- connectors = proxyConnectorMap.get( sourceId );
- } else {
- connectors = new ArrayList<>( );
- proxyConnectorMap.put( sourceId, connectors );
- }
- connectors.add( connector );
- }
-
- @Override
- public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
- {
- proxyConnectorMap.clear();
- for ( ProxyConnector connector : proxyConnectors )
- {
- addProxyConnector( connector );
- }
- }
- }
|