1 package org.apache.archiva.proxy;
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
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.checksum.ChecksumAlgorithm;
23 import org.apache.archiva.checksum.ChecksumUtil;
24 import org.apache.archiva.common.filelock.FileLockManager;
25 import org.apache.archiva.common.utils.PathUtil;
26 import org.apache.archiva.components.taskqueue.TaskQueueException;
27 import org.apache.archiva.configuration.ArchivaConfiguration;
28 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
29 import org.apache.archiva.configuration.ProxyConnectorRuleConfiguration;
30 import org.apache.archiva.policies.DownloadErrorPolicy;
31 import org.apache.archiva.policies.DownloadPolicy;
32 import org.apache.archiva.policies.Policy;
33 import org.apache.archiva.policies.PolicyConfigurationException;
34 import org.apache.archiva.policies.PolicyOption;
35 import org.apache.archiva.policies.PolicyViolationException;
36 import org.apache.archiva.policies.PostDownloadPolicy;
37 import org.apache.archiva.policies.PreDownloadPolicy;
38 import org.apache.archiva.policies.ProxyDownloadException;
39 import org.apache.archiva.policies.urlcache.UrlFailureCache;
40 import org.apache.archiva.proxy.model.NetworkProxy;
41 import org.apache.archiva.proxy.model.ProxyConnector;
42 import org.apache.archiva.proxy.model.ProxyFetchResult;
43 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
44 import org.apache.archiva.repository.ManagedRepository;
45 import org.apache.archiva.repository.RemoteRepository;
46 import org.apache.archiva.repository.RemoteRepositoryContent;
47 import org.apache.archiva.repository.RepositoryType;
48 import org.apache.archiva.repository.content.Artifact;
49 import org.apache.archiva.repository.content.ContentItem;
50 import org.apache.archiva.repository.content.ItemSelector;
51 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
52 import org.apache.archiva.repository.metadata.base.MetadataTools;
53 import org.apache.archiva.repository.storage.StorageAsset;
54 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
55 import org.apache.archiva.repository.storage.fs.FsStorageUtil;
56 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
57 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
58 import org.apache.commons.collections4.CollectionUtils;
59 import org.apache.commons.lang3.StringUtils;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62 import org.slf4j.MarkerFactory;
64 import javax.annotation.PostConstruct;
65 import javax.inject.Inject;
66 import javax.inject.Named;
67 import java.io.IOException;
68 import java.net.MalformedURLException;
69 import java.nio.file.Files;
70 import java.nio.file.Path;
71 import java.nio.file.StandardCopyOption;
72 import java.util.ArrayList;
73 import java.util.Collections;
74 import java.util.HashMap;
75 import java.util.LinkedHashMap;
76 import java.util.List;
78 import java.util.Properties;
79 import java.util.concurrent.ConcurrentHashMap;
80 import java.util.concurrent.ConcurrentMap;
82 public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
84 protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
86 protected UrlFailureCache urlFailureCache;
89 @Named(value = "metadataTools#default")
90 private MetadataTools metadataTools;
92 private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>( );
93 private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>( );
94 private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>( );
95 private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
98 @Named(value = "archivaTaskScheduler#repository")
99 private ArchivaTaskScheduler<RepositoryTask> scheduler;
102 private ArchivaConfiguration archivaConfiguration;
105 @Named(value = "fileLockManager#default")
106 private FileLockManager fileLockManager;
108 private Map<String, NetworkProxy> networkProxyMap = new ConcurrentHashMap<>();
109 private List<ChecksumAlgorithm> checksumAlgorithms;
112 public void initialize()
114 checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
117 private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
118 String targetRepository,
119 List<ProxyConnectorRuleConfiguration> all )
121 List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations = new ArrayList<>();
123 for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : all )
125 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectorRuleConfiguration.getProxyConnectors() )
127 if ( StringUtils.equals( sourceRepository, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
128 targetRepository, proxyConnector.getTargetRepoId() ) )
130 proxyConnectorRuleConfigurations.add( proxyConnectorRuleConfiguration );
135 return proxyConnectorRuleConfigurations;
139 public StorageAsset fetchFromProxies( ManagedRepository repository, Artifact artifact )
140 throws ProxyDownloadException
142 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
143 StorageAsset localFile = artifact.getAsset( );
145 Properties requestProperties = new Properties();
146 requestProperties.setProperty( "filetype", "artifact" );
147 requestProperties.setProperty( "version", artifact.getVersion().getId() );
148 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
150 List<ProxyConnector> connectors = getProxyConnectors( repository );
151 for ( ProxyConnector connector : connectors )
153 if ( !connector.isEnabled() )
158 RemoteRepository targetRepository = connector.getTargetRepository();
159 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
161 StorageAsset targetFile = targetRepository.getAsset( localFile.getPath( ) );
162 // Removing the leading '/' from the path
163 String targetPath = targetFile.getPath( ).substring( 1 );
166 StorageAsset downloadedFile =
167 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
170 if ( fileExists(downloadedFile) )
172 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
173 return downloadedFile;
176 catch ( NotFoundException e )
178 log.debug( "Artifact {} not found on repository \"{}\".", artifact.getId(),
179 targetRepository.getId() );
181 catch ( NotModifiedException e )
183 log.debug( "Artifact {} not updated on repository \"{}\".", artifact.getId(),
184 targetRepository.getId() );
186 catch ( ProxyException e )
188 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact,
189 targetRepository.getContent(), localFile, e, previousExceptions );
193 if ( !previousExceptions.isEmpty() )
195 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
196 previousExceptions );
199 log.debug( "Exhausted all target repositories, artifact {} not found.", artifact.getId() );
205 public StorageAsset fetchFromProxies( ManagedRepository repository, ItemSelector artifactSelector )
206 throws ProxyDownloadException
208 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
209 ContentItem item = repository.getContent( ).getItem( artifactSelector );
210 StorageAsset localFile = item.getAsset( );
212 Properties requestProperties = new Properties();
213 requestProperties.setProperty( "filetype", "artifact" );
214 requestProperties.setProperty( "version", artifactSelector.getVersion() );
215 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
217 List<ProxyConnector> connectors = getProxyConnectors( repository );
218 for ( ProxyConnector connector : connectors )
220 if ( !connector.isEnabled() )
225 RemoteRepository targetRepository = connector.getTargetRepository();
226 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
228 StorageAsset targetFile = targetRepository.getAsset( localFile.getPath( ) );
229 // Removing the leading '/' from the path
230 String targetPath = targetFile.getPath( ).substring( 1 );
233 StorageAsset downloadedFile =
234 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
237 if ( fileExists(downloadedFile) )
239 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
240 return downloadedFile;
243 catch ( NotFoundException e )
245 log.debug( "Artifact {} not found on repository \"{}\".", item,
246 targetRepository.getId() );
248 catch ( NotModifiedException e )
250 log.debug( "Artifact {} not updated on repository \"{}\".", item,
251 targetRepository.getId() );
253 catch ( ProxyException e )
255 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, item,
256 targetRepository.getContent(), localFile, e, previousExceptions );
260 if ( !previousExceptions.isEmpty() )
262 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
263 previousExceptions );
266 log.debug( "Exhausted all target repositories, artifact {} not found.", item );
272 public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
274 StorageAsset localFile = repository.getAsset( path );
276 // no update policies for these paths
277 if ( localFile.exists() )
282 Properties requestProperties = new Properties();
283 requestProperties.setProperty( "filetype", "resource" );
284 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
286 List<ProxyConnector> connectors = getProxyConnectors( repository );
287 for ( ProxyConnector connector : connectors )
289 if ( !connector.isEnabled() )
294 RemoteRepository targetRepository = connector.getTargetRepository();
295 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
297 String targetPath = path;
301 StorageAsset downloadedFile =
302 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
305 if ( fileExists( downloadedFile ) )
307 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
308 return downloadedFile;
311 catch ( NotFoundException e )
313 log.debug( "Resource {} not found on repository \"{}\".", path,
314 targetRepository.getId() );
316 catch ( NotModifiedException e )
318 log.debug( "Resource {} not updated on repository \"{}\".", path,
319 targetRepository.getId() );
321 catch ( ProxyException e )
324 "Transfer error from repository {} for resource {}, continuing to next repository. Error message: {}",
325 targetRepository.getId(), path, e.getMessage() );
326 log.debug( MarkerFactory.getDetachedMarker( "transfer.error" ),
327 "Transfer error from repository \"{}"
328 + "\" for resource {}, continuing to next repository. Error message: {}",
329 targetRepository.getId(), path, e.getMessage(), e );
334 log.debug( "Exhausted all target repositories, resource {} not found.", path );
340 public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String rawLogicalPath )
343 if (rawLogicalPath.startsWith( "/" )){
344 logicalPath = rawLogicalPath.substring( 1 );
346 logicalPath = rawLogicalPath;
348 StorageAsset localFile = repository.getAsset( logicalPath );
350 Properties requestProperties = new Properties();
351 requestProperties.setProperty( "filetype", "metadata" );
352 boolean metadataNeedsUpdating = false;
353 long originalTimestamp = getLastModified( localFile );
355 List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
356 for ( ProxyConnector connector : connectors )
358 if ( !connector.isEnabled() )
363 RemoteRepository targetRepository = connector.getTargetRepository();
365 StorageAsset localRepoFile = toLocalRepoFile( repository, targetRepository.getContent(), logicalPath );
366 long originalMetadataTimestamp = getLastModified( localRepoFile );
370 transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
373 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
375 metadataNeedsUpdating = true;
378 catch ( NotFoundException e )
381 log.debug( "Metadata {} not found on remote repository '{}'.", logicalPath,
382 targetRepository.getId(), e );
385 catch ( NotModifiedException e )
388 log.debug( "Metadata {} not updated on remote repository '{}'.", logicalPath,
389 targetRepository.getId(), e );
392 catch ( ProxyException e )
395 "Transfer error from repository {} for versioned Metadata {}, continuing to next repository. Error message: {}",
396 targetRepository.getId(), logicalPath, e.getMessage() );
397 log.debug( "Full stack trace", e );
401 if ( hasBeenUpdated( localFile, originalTimestamp ) )
403 metadataNeedsUpdating = true;
406 if ( metadataNeedsUpdating || !localFile.exists())
410 metadataTools.updateMetadata( repository.getContent(), logicalPath );
412 catch ( RepositoryMetadataException e )
414 log.warn( "Unable to update metadata {}:{}", localFile.getPath(), e.getMessage(), e );
419 if ( fileExists( localFile ) )
421 return new ProxyFetchResult( localFile, metadataNeedsUpdating );
424 return new ProxyFetchResult( null, false );
427 private long getLastModified(StorageAsset file )
429 if ( !file.exists() || file.isContainer() )
434 return file.getModificationTime().toEpochMilli();
437 private boolean hasBeenUpdated(StorageAsset file, long originalLastModified )
439 if ( !file.exists() || file.isContainer() )
444 long currentLastModified = getLastModified( file );
445 return ( currentLastModified > originalLastModified );
448 private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
451 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
452 return repository.getAsset( repoPath );
456 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
460 public boolean hasProxies( ManagedRepository repository )
462 synchronized ( this.proxyConnectorMap )
464 return this.proxyConnectorMap.containsKey( repository.getId() );
469 * Simple method to test if the file exists on the local disk.
471 * @param file the file to test. (may be null)
472 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
474 private boolean fileExists( StorageAsset file )
486 return !file.isContainer();
490 * Perform the transfer of the file.
492 * @param connector the connector configuration to use.
493 * @param remoteRepository the remote repository get the resource from.
494 * @param remotePath the path in the remote repository to the resource to get.
495 * @param repository the managed repository that will hold the file
496 * @param resource the path relative to the repository storage where the file should be downloaded to
497 * @param requestProperties the request properties to utilize for policy handling.
498 * @param executeConsumers whether to execute the consumers after proxying
499 * @return the local file that was downloaded, or null if not downloaded.
500 * @throws NotFoundException if the file was not found on the remote repository.
501 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, but
502 * the remote resource is not newer than the local File.
503 * @throws ProxyException if transfer was unsuccessful.
505 protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
506 ManagedRepository repository, StorageAsset resource, Properties requestProperties,
507 boolean executeConsumers )
508 throws ProxyException, NotModifiedException
513 url = remoteRepository.getLocation().toURL().toString();
515 catch ( MalformedURLException e )
517 throw new ProxyException( e.getMessage(), e );
519 if ( !url.endsWith( "/" ) )
523 if (remotePath.startsWith( "/" )) {
524 url = url + remotePath.substring( 1 );
526 url = url + remotePath;
528 requestProperties.setProperty( "url", url );
530 // Is a whitelist defined?
531 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
533 // Path must belong to whitelist.
534 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
536 log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
537 remotePath, remoteRepository.getId() );
542 // Is target path part of blacklist?
543 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
545 log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
546 remoteRepository.getId() );
550 // Handle pre-download policy
553 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, resource );
555 catch ( PolicyViolationException e )
557 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
558 if ( resource.exists() )
560 log.debug( "{} : using already present local file.", emsg );
568 Path workingDirectory = createWorkingDirectory( repository );
569 FilesystemStorage tmpStorage = null;
572 tmpStorage = new FilesystemStorage( workingDirectory, fileLockManager );
574 catch ( IOException e )
576 throw new ProxyException( "Could not create tmp storage" );
578 StorageAsset tmpResource = tmpStorage.getAsset( resource.getName( ) );
579 StorageAsset[] tmpChecksumFiles = new StorageAsset[checksumAlgorithms.size()];
580 for(int i=0; i<checksumAlgorithms.size(); i++) {
581 ChecksumAlgorithm alg = checksumAlgorithms.get( i );
582 tmpChecksumFiles[i] = tmpStorage.getAsset( resource.getName() + "." + alg.getDefaultExtension() );
588 transferResources( connector, remoteRepository, tmpResource,tmpChecksumFiles , url, remotePath,
589 resource, workingDirectory, repository );
591 // Handle post-download policies.
594 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, tmpResource );
596 catch ( PolicyViolationException e )
598 log.warn( "Transfer invalidated from {} : {}", url, e.getMessage() );
599 executeConsumers = false;
600 if ( !fileExists( tmpResource ) )
606 if ( resource != null )
608 synchronized ( resource.getPath().intern() )
610 StorageAsset directory = resource.getParent();
611 for (int i=0; i<tmpChecksumFiles.length; i++) {
612 moveFileIfExists( tmpChecksumFiles[i], directory );
614 moveFileIfExists( tmpResource, directory );
620 org.apache.archiva.common.utils.FileUtils.deleteQuietly( workingDirectory );
623 if ( executeConsumers )
625 // Just-in-time update of the index and database by executing the consumers for this artifact
626 //consumers.executeConsumers( connector.getSourceRepository().getRepository(), resource );
627 queueRepositoryTask( connector.getSourceRepository().getId(), resource );
633 protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
634 StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
635 ManagedRepository repository ) throws ProxyException;
637 private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
639 RepositoryTask task = new RepositoryTask();
640 task.setRepositoryId( repositoryId );
641 task.setResourceFile( localFile );
642 task.setUpdateRelatedArtifacts( true );
643 task.setScanAll( true );
647 scheduler.queueTask( task );
649 catch ( TaskQueueException e )
651 log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
652 + "'].", localFile.getName() );
657 * Moves the file into repository location if it exists
659 * @param fileToMove this could be either the main artifact, sha1 or md5 checksum file.
660 * @param directory directory to write files to
662 private void moveFileIfExists( StorageAsset fileToMove, StorageAsset directory )
663 throws ProxyException
665 if ( fileToMove != null && fileToMove.exists() )
667 StorageAsset newLocation = directory.getStorage().getAsset( directory.getPath()+ "/" + fileToMove.getName());
668 moveTempToTarget( fileToMove, newLocation );
673 * Apply the policies.
675 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
676 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy
678 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)}
680 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
681 * @throws PolicyViolationException
683 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
684 Properties request, StorageAsset localFile )
685 throws PolicyViolationException
687 for ( Map.Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
689 // olamy with spring rolehint is now downloadPolicy#hint
690 // so substring after last # to get the hint as with plexus
691 String key = entry.getValue( ).getId( );
692 DownloadPolicy policy = entry.getValue();
693 PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
695 log.debug( "Applying [{}] policy with [{}]", key, option );
698 policy.applyPolicy( option, request, localFile );
700 catch ( PolicyConfigurationException e )
702 log.error( e.getMessage(), e );
707 private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
708 Properties request, ContentItem artifact, RemoteRepositoryContent content,
709 StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
710 throws ProxyDownloadException
712 boolean process = true;
713 for ( Map.Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() )
716 // olamy with spring rolehint is now downloadPolicy#hint
717 // so substring after last # to get the hint as with plexus
718 String key = entry.getValue( ).getId( );
719 DownloadErrorPolicy policy = entry.getValue();
720 PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
722 log.debug( "Applying [{}] policy with [{}]", key, option );
725 // all policies must approve the exception, any can cancel
726 process = policy.applyPolicy( option, request, localFile, exception, previousExceptions );
732 catch ( PolicyConfigurationException e )
734 log.error( e.getMessage(), e );
740 // if the exception was queued, don't throw it
741 if ( !previousExceptions.containsKey( content.getId() ) )
743 throw new ProxyDownloadException(
744 "An error occurred in downloading from the remote repository, and the policy is to fail immediately",
745 content.getId(), exception );
750 // if the exception was queued, but cancelled, remove it
751 previousExceptions.remove( content.getId() );
755 "Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
756 content.getRepository().getId(), artifact, exception.getMessage() );
757 log.debug( "Full stack trace", exception );
761 * Creates a working directory
764 * @return file location of working directory
766 private Path createWorkingDirectory( ManagedRepository repository )
770 return Files.createTempDirectory( "temp" );
772 catch ( IOException e )
774 throw new RuntimeException( e.getMessage(), e );
780 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles its
783 * @param temp The completed download file
784 * @param target The final location of the downloaded file
785 * @throws ProxyException when the temp file cannot replace the target file
787 private void moveTempToTarget( StorageAsset temp, StorageAsset target )
788 throws ProxyException
793 org.apache.archiva.repository.storage.util.StorageUtil.moveAsset( temp, target, true , StandardCopyOption.REPLACE_EXISTING);
795 catch ( IOException e )
797 log.error( "Move failed from {} to {}, trying copy.", temp, target );
800 FsStorageUtil.copyAsset( temp, target, true );
802 temp.getStorage( ).removeAsset( temp );
805 catch ( IOException ex )
807 log.error("Copy failed from {} to {}: ({}) {}", temp, target, e.getClass(), e.getMessage());
808 throw new ProxyException("Could not move temp file "+temp.getPath()+" to target "+target.getPath()+": ("+e.getClass()+") "+e.getMessage(), e);
814 * Tests whitelist and blacklist patterns against path.
816 * @param path the path to test.
817 * @param patterns the list of patterns to check.
818 * @return true if the path matches at least 1 pattern in the provided patterns list.
820 private boolean matchesPattern( String path, List<String> patterns )
822 if ( CollectionUtils.isEmpty( patterns ) )
827 if ( !path.startsWith( "/" ) )
832 for ( String pattern : patterns )
834 if ( !pattern.startsWith( "/" ) )
836 pattern = "/" + pattern;
839 if ( PathUtil.matchPath( pattern, path, false ) )
849 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
853 public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
856 if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
858 return Collections.emptyList();
860 List<ProxyConnector> ret = new ArrayList<>( this.proxyConnectorMap.get( repository.getId() ) );
862 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
868 protected String addParameters(String path, RemoteRepository remoteRepository )
870 if ( remoteRepository.getExtraParameters().isEmpty() )
875 boolean question = false;
877 StringBuilder res = new StringBuilder( path == null ? "" : path );
879 for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters().entrySet() )
883 res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() );
887 return res.toString();
890 public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
892 this.archivaConfiguration = archivaConfiguration;
895 public MetadataTools getMetadataTools()
897 return metadataTools;
900 public void setMetadataTools(MetadataTools metadataTools )
902 this.metadataTools = metadataTools;
905 public UrlFailureCache getUrlFailureCache()
907 return urlFailureCache;
910 public void setUrlFailureCache(UrlFailureCache urlFailureCache )
912 this.urlFailureCache = urlFailureCache;
915 public Map<String, PreDownloadPolicy> getPreDownloadPolicies()
917 return preDownloadPolicies;
920 public void setPreDownloadPolicies(Map<String, PreDownloadPolicy> preDownloadPolicies )
922 this.preDownloadPolicies = preDownloadPolicies;
925 public Map<String, PostDownloadPolicy> getPostDownloadPolicies()
927 return postDownloadPolicies;
930 public void setPostDownloadPolicies(Map<String, PostDownloadPolicy> postDownloadPolicies )
932 this.postDownloadPolicies = postDownloadPolicies;
935 public Map<String, DownloadErrorPolicy> getDownloadErrorPolicies()
937 return downloadErrorPolicies;
940 public void setDownloadErrorPolicies(Map<String, DownloadErrorPolicy> downloadErrorPolicies )
942 this.downloadErrorPolicies = downloadErrorPolicies;
946 public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
947 this.networkProxyMap.clear();
948 this.networkProxyMap.putAll( networkProxies );
952 public NetworkProxy getNetworkProxy(String id) {
953 return this.networkProxyMap.get(id);
957 public Map<String, NetworkProxy> getNetworkProxies() {
958 return this.networkProxyMap;
962 public abstract List<RepositoryType> supports();
965 public void setPolicies( List<Policy> policyList )
967 preDownloadPolicies.clear();
968 postDownloadPolicies.clear();
969 downloadErrorPolicies.clear();
970 for (Policy policy : policyList) {
975 void addPolicy(PreDownloadPolicy policy) {
976 preDownloadPolicies.put( policy.getId( ), policy );
979 void addPolicy(PostDownloadPolicy policy) {
980 postDownloadPolicies.put( policy.getId( ), policy );
982 void addPolicy(DownloadErrorPolicy policy) {
983 downloadErrorPolicies.put( policy.getId( ), policy );
987 public void addPolicy( Policy policy )
989 if (policy instanceof PreDownloadPolicy) {
990 addPolicy( (PreDownloadPolicy)policy );
991 } else if (policy instanceof PostDownloadPolicy) {
992 addPolicy( (PostDownloadPolicy) policy );
993 } else if (policy instanceof DownloadErrorPolicy) {
994 addPolicy( (DownloadErrorPolicy) policy );
996 log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
1001 public void removePolicy( Policy policy )
1003 final String id = policy.getId();
1004 if (preDownloadPolicies.containsKey( id )) {
1005 preDownloadPolicies.remove( id );
1006 } else if (postDownloadPolicies.containsKey( id )) {
1007 postDownloadPolicies.remove( id );
1008 } else if (downloadErrorPolicies.containsKey( id )) {
1009 downloadErrorPolicies.remove( id );
1014 public void addProxyConnector( ProxyConnector connector )
1016 final String sourceId = connector.getSourceRepository( ).getId( );
1017 List<ProxyConnector> connectors;
1018 if (proxyConnectorMap.containsKey( sourceId )) {
1019 connectors = proxyConnectorMap.get( sourceId );
1021 connectors = new ArrayList<>( );
1022 proxyConnectorMap.put( sourceId, connectors );
1024 connectors.add( connector );
1028 public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
1030 proxyConnectorMap.clear();
1031 for ( ProxyConnector connector : proxyConnectors )
1033 addProxyConnector( connector );