1 package org.apache.archiva.proxy.base;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import org.apache.archiva.checksum.ChecksumAlgorithm;
22 import org.apache.archiva.checksum.ChecksumUtil;
23 import org.apache.archiva.common.filelock.FileLockManager;
24 import org.apache.archiva.common.utils.PathUtil;
25 import org.apache.archiva.components.taskqueue.TaskQueueException;
26 import org.apache.archiva.configuration.ArchivaConfiguration;
27 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
28 import org.apache.archiva.configuration.ProxyConnectorRuleConfiguration;
29 import org.apache.archiva.policies.DownloadErrorPolicy;
30 import org.apache.archiva.policies.DownloadPolicy;
31 import org.apache.archiva.policies.Policy;
32 import org.apache.archiva.policies.PolicyConfigurationException;
33 import org.apache.archiva.policies.PolicyOption;
34 import org.apache.archiva.policies.PolicyViolationException;
35 import org.apache.archiva.policies.PostDownloadPolicy;
36 import org.apache.archiva.policies.PreDownloadPolicy;
37 import org.apache.archiva.policies.ProxyDownloadException;
38 import org.apache.archiva.policies.urlcache.UrlFailureCache;
39 import org.apache.archiva.proxy.model.NetworkProxy;
40 import org.apache.archiva.proxy.model.ProxyConnector;
41 import org.apache.archiva.proxy.model.ProxyFetchResult;
42 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
43 import org.apache.archiva.repository.ManagedRepository;
44 import org.apache.archiva.repository.RemoteRepository;
45 import org.apache.archiva.repository.RemoteRepositoryContent;
46 import org.apache.archiva.repository.RepositoryType;
47 import org.apache.archiva.repository.content.Artifact;
48 import org.apache.archiva.repository.content.ContentItem;
49 import org.apache.archiva.repository.content.ItemSelector;
50 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
51 import org.apache.archiva.repository.metadata.base.MetadataTools;
52 import org.apache.archiva.repository.storage.StorageAsset;
53 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
54 import org.apache.archiva.repository.storage.fs.FsStorageUtil;
55 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
56 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
57 import org.apache.commons.collections4.CollectionUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61 import org.slf4j.MarkerFactory;
63 import javax.annotation.PostConstruct;
64 import javax.inject.Inject;
65 import javax.inject.Named;
66 import java.io.IOException;
67 import java.net.MalformedURLException;
68 import java.nio.file.Files;
69 import java.nio.file.Path;
70 import java.nio.file.StandardCopyOption;
71 import java.util.ArrayList;
72 import java.util.Collections;
73 import java.util.HashMap;
74 import java.util.LinkedHashMap;
75 import java.util.List;
77 import java.util.Properties;
78 import java.util.concurrent.ConcurrentHashMap;
79 import java.util.concurrent.ConcurrentMap;
81 public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
83 protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
85 protected UrlFailureCache urlFailureCache;
88 @Named(value = "metadataTools#default")
89 private MetadataTools metadataTools;
91 private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>( );
92 private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>( );
93 private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>( );
94 private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
97 @Named(value = "archivaTaskScheduler#repository")
98 private ArchivaTaskScheduler<RepositoryTask> scheduler;
101 private ArchivaConfiguration archivaConfiguration;
104 @Named(value = "fileLockManager#default")
105 private FileLockManager fileLockManager;
107 private Map<String, NetworkProxy> networkProxyMap = new ConcurrentHashMap<>();
108 private List<ChecksumAlgorithm> checksumAlgorithms;
111 public void initialize()
113 checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
116 private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
117 String targetRepository,
118 List<ProxyConnectorRuleConfiguration> all )
120 List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations = new ArrayList<>();
122 for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : all )
124 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectorRuleConfiguration.getProxyConnectors() )
126 if ( StringUtils.equals( sourceRepository, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
127 targetRepository, proxyConnector.getTargetRepoId() ) )
129 proxyConnectorRuleConfigurations.add( proxyConnectorRuleConfiguration );
134 return proxyConnectorRuleConfigurations;
138 public StorageAsset fetchFromProxies( ManagedRepository repository, Artifact artifact )
139 throws ProxyDownloadException
141 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
142 StorageAsset localFile = artifact.getAsset( );
144 Properties requestProperties = new Properties();
145 requestProperties.setProperty( "filetype", "artifact" );
146 requestProperties.setProperty( "version", artifact.getVersion().getId() );
147 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
149 List<ProxyConnector> connectors = getProxyConnectors( repository );
150 for ( ProxyConnector connector : connectors )
152 if ( !connector.isEnabled() )
157 RemoteRepository targetRepository = connector.getTargetRepository();
158 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
160 StorageAsset targetFile = targetRepository.getAsset( localFile.getPath( ) );
161 // Removing the leading '/' from the path
162 String targetPath = targetFile.getPath( ).substring( 1 );
165 StorageAsset downloadedFile =
166 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
169 if ( fileExists(downloadedFile) )
171 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
172 return downloadedFile;
175 catch ( NotFoundException e )
177 log.debug( "Artifact {} not found on repository \"{}\".", artifact.getId(),
178 targetRepository.getId() );
180 catch ( NotModifiedException e )
182 log.debug( "Artifact {} not updated on repository \"{}\".", artifact.getId(),
183 targetRepository.getId() );
185 catch ( ProxyException e )
187 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact,
188 targetRepository.getContent(), localFile, e, previousExceptions );
192 if ( !previousExceptions.isEmpty() )
194 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
195 previousExceptions );
198 log.debug( "Exhausted all target repositories, artifact {} not found.", artifact.getId() );
204 public StorageAsset fetchFromProxies( ManagedRepository repository, ItemSelector artifactSelector )
205 throws ProxyDownloadException
207 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
208 ContentItem item = repository.getContent( ).getItem( artifactSelector );
209 StorageAsset localFile = item.getAsset( );
211 Properties requestProperties = new Properties();
212 requestProperties.setProperty( "filetype", "artifact" );
213 requestProperties.setProperty( "version", artifactSelector.getVersion() );
214 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
216 List<ProxyConnector> connectors = getProxyConnectors( repository );
217 for ( ProxyConnector connector : connectors )
219 if ( !connector.isEnabled() )
224 RemoteRepository targetRepository = connector.getTargetRepository();
225 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
227 StorageAsset targetFile = targetRepository.getAsset( localFile.getPath( ) );
228 // Removing the leading '/' from the path
229 String targetPath = targetFile.getPath( ).substring( 1 );
232 StorageAsset downloadedFile =
233 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
236 if ( fileExists(downloadedFile) )
238 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
239 return downloadedFile;
242 catch ( NotFoundException e )
244 log.debug( "Artifact {} not found on repository \"{}\".", item,
245 targetRepository.getId() );
247 catch ( NotModifiedException e )
249 log.debug( "Artifact {} not updated on repository \"{}\".", item,
250 targetRepository.getId() );
252 catch ( ProxyException e )
254 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, item,
255 targetRepository.getContent(), localFile, e, previousExceptions );
259 if ( !previousExceptions.isEmpty() )
261 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
262 previousExceptions );
265 log.debug( "Exhausted all target repositories, artifact {} not found.", item );
271 public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
273 StorageAsset localFile = repository.getAsset( path );
275 // no update policies for these paths
276 if ( localFile.exists() )
281 Properties requestProperties = new Properties();
282 requestProperties.setProperty( "filetype", "resource" );
283 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
285 List<ProxyConnector> connectors = getProxyConnectors( repository );
286 for ( ProxyConnector connector : connectors )
288 if ( !connector.isEnabled() )
293 RemoteRepository targetRepository = connector.getTargetRepository();
294 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
296 String targetPath = path;
300 StorageAsset downloadedFile =
301 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
304 if ( fileExists( downloadedFile ) )
306 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
307 return downloadedFile;
310 catch ( NotFoundException e )
312 log.debug( "Resource {} not found on repository \"{}\".", path,
313 targetRepository.getId() );
315 catch ( NotModifiedException e )
317 log.debug( "Resource {} not updated on repository \"{}\".", path,
318 targetRepository.getId() );
320 catch ( ProxyException e )
323 "Transfer error from repository {} for resource {}, continuing to next repository. Error message: {}",
324 targetRepository.getId(), path, e.getMessage() );
325 log.debug( MarkerFactory.getDetachedMarker( "transfer.error" ),
326 "Transfer error from repository \"{}"
327 + "\" for resource {}, continuing to next repository. Error message: {}",
328 targetRepository.getId(), path, e.getMessage(), e );
333 log.debug( "Exhausted all target repositories, resource {} not found.", path );
339 public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String rawLogicalPath )
342 if (rawLogicalPath.startsWith( "/" )){
343 logicalPath = rawLogicalPath.substring( 1 );
345 logicalPath = rawLogicalPath;
347 StorageAsset localFile = repository.getAsset( logicalPath );
349 Properties requestProperties = new Properties();
350 requestProperties.setProperty( "filetype", "metadata" );
351 boolean metadataNeedsUpdating = false;
352 long originalTimestamp = getLastModified( localFile );
354 List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
355 for ( ProxyConnector connector : connectors )
357 if ( !connector.isEnabled() )
362 RemoteRepository targetRepository = connector.getTargetRepository();
364 StorageAsset localRepoFile = toLocalRepoFile( repository, targetRepository.getContent(), logicalPath );
365 long originalMetadataTimestamp = getLastModified( localRepoFile );
369 transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
372 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
374 metadataNeedsUpdating = true;
377 catch ( NotFoundException e )
380 log.debug( "Metadata {} not found on remote repository '{}'.", logicalPath,
381 targetRepository.getId(), e );
384 catch ( NotModifiedException e )
387 log.debug( "Metadata {} not updated on remote repository '{}'.", logicalPath,
388 targetRepository.getId(), e );
391 catch ( ProxyException e )
394 "Transfer error from repository {} for versioned Metadata {}, continuing to next repository. Error message: {}",
395 targetRepository.getId(), logicalPath, e.getMessage() );
396 log.debug( "Full stack trace", e );
400 if ( hasBeenUpdated( localFile, originalTimestamp ) )
402 metadataNeedsUpdating = true;
405 if ( metadataNeedsUpdating || !localFile.exists())
409 metadataTools.updateMetadata( repository.getContent(), logicalPath );
411 catch ( RepositoryMetadataException e )
413 log.warn( "Unable to update metadata {}:{}", localFile.getPath(), e.getMessage(), e );
418 if ( fileExists( localFile ) )
420 return new ProxyFetchResult( localFile, metadataNeedsUpdating );
423 return new ProxyFetchResult( null, false );
426 private long getLastModified(StorageAsset file )
428 if ( !file.exists() || file.isContainer() )
433 return file.getModificationTime().toEpochMilli();
436 private boolean hasBeenUpdated(StorageAsset file, long originalLastModified )
438 if ( !file.exists() || file.isContainer() )
443 long currentLastModified = getLastModified( file );
444 return ( currentLastModified > originalLastModified );
447 private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
450 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
451 return repository.getAsset( repoPath );
455 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
459 public boolean hasProxies( ManagedRepository repository )
461 synchronized ( this.proxyConnectorMap )
463 return this.proxyConnectorMap.containsKey( repository.getId() );
468 * Simple method to test if the file exists on the local disk.
470 * @param file the file to test. (may be null)
471 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
473 private boolean fileExists( StorageAsset file )
485 return !file.isContainer();
489 * Perform the transfer of the file.
491 * @param connector the connector configuration to use.
492 * @param remoteRepository the remote repository get the resource from.
493 * @param remotePath the path in the remote repository to the resource to get.
494 * @param repository the managed repository that will hold the file
495 * @param resource the path relative to the repository storage where the file should be downloaded to
496 * @param requestProperties the request properties to utilize for policy handling.
497 * @param executeConsumers whether to execute the consumers after proxying
498 * @return the local file that was downloaded, or null if not downloaded.
499 * @throws NotFoundException if the file was not found on the remote repository.
500 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, but
501 * the remote resource is not newer than the local File.
502 * @throws ProxyException if transfer was unsuccessful.
504 protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
505 ManagedRepository repository, StorageAsset resource, Properties requestProperties,
506 boolean executeConsumers )
507 throws ProxyException, NotModifiedException
512 url = remoteRepository.getLocation().toURL().toString();
514 catch ( MalformedURLException e )
516 throw new ProxyException( e.getMessage(), e );
518 if ( !url.endsWith( "/" ) )
522 if (remotePath.startsWith( "/" )) {
523 url = url + remotePath.substring( 1 );
525 url = url + remotePath;
527 requestProperties.setProperty( "url", url );
529 // Is a whitelist defined?
530 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
532 // Path must belong to whitelist.
533 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
535 log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
536 remotePath, remoteRepository.getId() );
541 // Is target path part of blacklist?
542 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
544 log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
545 remoteRepository.getId() );
549 // Handle pre-download policy
552 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, resource );
554 catch ( PolicyViolationException e )
556 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
557 if ( resource.exists() )
559 log.debug( "{} : using already present local file.", emsg );
567 Path workingDirectory = createWorkingDirectory( repository );
568 FilesystemStorage tmpStorage = null;
571 tmpStorage = new FilesystemStorage( workingDirectory, fileLockManager );
573 catch ( IOException e )
575 throw new ProxyException( "Could not create tmp storage" );
577 StorageAsset tmpResource = tmpStorage.getAsset( resource.getName( ) );
578 StorageAsset[] tmpChecksumFiles = new StorageAsset[checksumAlgorithms.size()];
579 for(int i=0; i<checksumAlgorithms.size(); i++) {
580 ChecksumAlgorithm alg = checksumAlgorithms.get( i );
581 tmpChecksumFiles[i] = tmpStorage.getAsset( resource.getName() + "." + alg.getDefaultExtension() );
587 transferResources( connector, remoteRepository, tmpResource,tmpChecksumFiles , url, remotePath,
588 resource, workingDirectory, repository );
590 // Handle post-download policies.
593 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, tmpResource );
595 catch ( PolicyViolationException e )
597 log.warn( "Transfer invalidated from {} : {}", url, e.getMessage() );
598 executeConsumers = false;
599 if ( !fileExists( tmpResource ) )
605 if ( resource != null )
607 synchronized ( resource.getPath().intern() )
609 StorageAsset directory = resource.getParent();
610 for (int i=0; i<tmpChecksumFiles.length; i++) {
611 moveFileIfExists( tmpChecksumFiles[i], directory );
613 moveFileIfExists( tmpResource, directory );
619 org.apache.archiva.common.utils.FileUtils.deleteQuietly( workingDirectory );
622 if ( executeConsumers )
624 // Just-in-time update of the index and database by executing the consumers for this artifact
625 //consumers.executeConsumers( connector.getSourceRepository().getRepository(), resource );
626 queueRepositoryTask( connector.getSourceRepository().getId(), resource );
632 protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
633 StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
634 ManagedRepository repository ) throws ProxyException;
636 private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
638 RepositoryTask task = new RepositoryTask();
639 task.setRepositoryId( repositoryId );
640 task.setResourceFile( localFile );
641 task.setUpdateRelatedArtifacts( true );
642 task.setScanAll( true );
646 scheduler.queueTask( task );
648 catch ( TaskQueueException e )
650 log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
651 + "'].", localFile.getName() );
656 * Moves the file into repository location if it exists
658 * @param fileToMove this could be either the main artifact, sha1 or md5 checksum file.
659 * @param directory directory to write files to
661 private void moveFileIfExists( StorageAsset fileToMove, StorageAsset directory )
662 throws ProxyException
664 if ( fileToMove != null && fileToMove.exists() )
666 StorageAsset newLocation = directory.getStorage().getAsset( directory.getPath()+ "/" + fileToMove.getName());
667 moveTempToTarget( fileToMove, newLocation );
672 * Apply the policies.
674 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
675 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy
677 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)}
679 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
680 * @throws PolicyViolationException
682 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
683 Properties request, StorageAsset localFile )
684 throws PolicyViolationException
686 for ( Map.Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
688 // olamy with spring rolehint is now downloadPolicy#hint
689 // so substring after last # to get the hint as with plexus
690 String key = entry.getValue( ).getId( );
691 DownloadPolicy policy = entry.getValue();
692 PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
694 log.debug( "Applying [{}] policy with [{}]", key, option );
697 policy.applyPolicy( option, request, localFile );
699 catch ( PolicyConfigurationException e )
701 log.error( e.getMessage(), e );
706 private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
707 Properties request, ContentItem artifact, RemoteRepositoryContent content,
708 StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
709 throws ProxyDownloadException
711 boolean process = true;
712 for ( Map.Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() )
715 // olamy with spring rolehint is now downloadPolicy#hint
716 // so substring after last # to get the hint as with plexus
717 String key = entry.getValue( ).getId( );
718 DownloadErrorPolicy policy = entry.getValue();
719 PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
721 log.debug( "Applying [{}] policy with [{}]", key, option );
724 // all policies must approve the exception, any can cancel
725 process = policy.applyPolicy( option, request, localFile, exception, previousExceptions );
731 catch ( PolicyConfigurationException e )
733 log.error( e.getMessage(), e );
739 // if the exception was queued, don't throw it
740 if ( !previousExceptions.containsKey( content.getId() ) )
742 throw new ProxyDownloadException(
743 "An error occurred in downloading from the remote repository, and the policy is to fail immediately",
744 content.getId(), exception );
749 // if the exception was queued, but cancelled, remove it
750 previousExceptions.remove( content.getId() );
754 "Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
755 content.getRepository().getId(), artifact, exception.getMessage() );
756 log.debug( "Full stack trace", exception );
760 * Creates a working directory
763 * @return file location of working directory
765 private Path createWorkingDirectory( ManagedRepository repository )
769 return Files.createTempDirectory( "temp" );
771 catch ( IOException e )
773 throw new RuntimeException( e.getMessage(), e );
779 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles its
782 * @param temp The completed download file
783 * @param target The final location of the downloaded file
784 * @throws ProxyException when the temp file cannot replace the target file
786 private void moveTempToTarget( StorageAsset temp, StorageAsset target )
787 throws ProxyException
792 org.apache.archiva.repository.storage.util.StorageUtil.moveAsset( temp, target, true , StandardCopyOption.REPLACE_EXISTING);
794 catch ( IOException e )
796 log.error( "Move failed from {} to {}, trying copy.", temp, target );
799 FsStorageUtil.copyAsset( temp, target, true );
801 temp.getStorage( ).removeAsset( temp );
804 catch ( IOException ex )
806 log.error("Copy failed from {} to {}: ({}) {}", temp, target, e.getClass(), e.getMessage());
807 throw new ProxyException("Could not move temp file "+temp.getPath()+" to target "+target.getPath()+": ("+e.getClass()+") "+e.getMessage(), e);
813 * Tests whitelist and blacklist patterns against path.
815 * @param path the path to test.
816 * @param patterns the list of patterns to check.
817 * @return true if the path matches at least 1 pattern in the provided patterns list.
819 private boolean matchesPattern( String path, List<String> patterns )
821 if ( CollectionUtils.isEmpty( patterns ) )
826 if ( !path.startsWith( "/" ) )
831 for ( String pattern : patterns )
833 if ( !pattern.startsWith( "/" ) )
835 pattern = "/" + pattern;
838 if ( PathUtil.matchPath( pattern, path, false ) )
848 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
852 public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
855 if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
857 return Collections.emptyList();
859 List<ProxyConnector> ret = new ArrayList<>( this.proxyConnectorMap.get( repository.getId() ) );
861 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
867 protected String addParameters(String path, RemoteRepository remoteRepository )
869 if ( remoteRepository.getExtraParameters().isEmpty() )
874 boolean question = false;
876 StringBuilder res = new StringBuilder( path == null ? "" : path );
878 for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters().entrySet() )
882 res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() );
886 return res.toString();
889 public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
891 this.archivaConfiguration = archivaConfiguration;
894 public MetadataTools getMetadataTools()
896 return metadataTools;
899 public void setMetadataTools(MetadataTools metadataTools )
901 this.metadataTools = metadataTools;
904 public UrlFailureCache getUrlFailureCache()
906 return urlFailureCache;
909 public void setUrlFailureCache(UrlFailureCache urlFailureCache )
911 this.urlFailureCache = urlFailureCache;
914 public Map<String, PreDownloadPolicy> getPreDownloadPolicies()
916 return preDownloadPolicies;
919 public void setPreDownloadPolicies(Map<String, PreDownloadPolicy> preDownloadPolicies )
921 this.preDownloadPolicies = preDownloadPolicies;
924 public Map<String, PostDownloadPolicy> getPostDownloadPolicies()
926 return postDownloadPolicies;
929 public void setPostDownloadPolicies(Map<String, PostDownloadPolicy> postDownloadPolicies )
931 this.postDownloadPolicies = postDownloadPolicies;
934 public Map<String, DownloadErrorPolicy> getDownloadErrorPolicies()
936 return downloadErrorPolicies;
939 public void setDownloadErrorPolicies(Map<String, DownloadErrorPolicy> downloadErrorPolicies )
941 this.downloadErrorPolicies = downloadErrorPolicies;
945 public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
946 this.networkProxyMap.clear();
947 this.networkProxyMap.putAll( networkProxies );
951 public NetworkProxy getNetworkProxy(String id) {
952 return this.networkProxyMap.get(id);
956 public Map<String, NetworkProxy> getNetworkProxies() {
957 return this.networkProxyMap;
961 public abstract List<RepositoryType> supports();
964 public void setPolicies( List<Policy> policyList )
966 preDownloadPolicies.clear();
967 postDownloadPolicies.clear();
968 downloadErrorPolicies.clear();
969 for (Policy policy : policyList) {
974 void addPolicy(PreDownloadPolicy policy) {
975 preDownloadPolicies.put( policy.getId( ), policy );
978 void addPolicy(PostDownloadPolicy policy) {
979 postDownloadPolicies.put( policy.getId( ), policy );
981 void addPolicy(DownloadErrorPolicy policy) {
982 downloadErrorPolicies.put( policy.getId( ), policy );
986 public void addPolicy( Policy policy )
988 if (policy instanceof PreDownloadPolicy) {
989 addPolicy( (PreDownloadPolicy)policy );
990 } else if (policy instanceof PostDownloadPolicy) {
991 addPolicy( (PostDownloadPolicy) policy );
992 } else if (policy instanceof DownloadErrorPolicy) {
993 addPolicy( (DownloadErrorPolicy) policy );
995 log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
1000 public void removePolicy( Policy policy )
1002 final String id = policy.getId();
1003 if (preDownloadPolicies.containsKey( id )) {
1004 preDownloadPolicies.remove( id );
1005 } else if (postDownloadPolicies.containsKey( id )) {
1006 postDownloadPolicies.remove( id );
1007 } else if (downloadErrorPolicies.containsKey( id )) {
1008 downloadErrorPolicies.remove( id );
1013 public void addProxyConnector( ProxyConnector connector )
1015 final String sourceId = connector.getSourceRepository( ).getId( );
1016 List<ProxyConnector> connectors;
1017 if (proxyConnectorMap.containsKey( sourceId )) {
1018 connectors = proxyConnectorMap.get( sourceId );
1020 connectors = new ArrayList<>( );
1021 proxyConnectorMap.put( sourceId, connectors );
1023 connectors.add( connector );
1027 public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
1029 proxyConnectorMap.clear();
1030 for ( ProxyConnector connector : proxyConnectors )
1032 addProxyConnector( connector );