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.configuration.ArchivaConfiguration;
27 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
28 import org.apache.archiva.configuration.ProxyConnectorRuleConfiguration;
29 import org.apache.archiva.model.ArtifactReference;
30 import org.apache.archiva.model.Keys;
31 import org.apache.archiva.policies.DownloadErrorPolicy;
32 import org.apache.archiva.policies.DownloadPolicy;
33 import org.apache.archiva.policies.Policy;
34 import org.apache.archiva.policies.PolicyConfigurationException;
35 import org.apache.archiva.policies.PolicyOption;
36 import org.apache.archiva.policies.PolicyViolationException;
37 import org.apache.archiva.policies.PostDownloadPolicy;
38 import org.apache.archiva.policies.PreDownloadPolicy;
39 import org.apache.archiva.policies.ProxyDownloadException;
40 import org.apache.archiva.policies.urlcache.UrlFailureCache;
41 import org.apache.archiva.proxy.model.NetworkProxy;
42 import org.apache.archiva.proxy.model.ProxyConnector;
43 import org.apache.archiva.proxy.model.ProxyFetchResult;
44 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
45 import org.apache.archiva.components.taskqueue.TaskQueueException;
46 import org.apache.archiva.repository.BaseRepositoryContentLayout;
47 import org.apache.archiva.repository.LayoutException;
48 import org.apache.archiva.repository.ManagedRepository;
49 import org.apache.archiva.repository.RemoteRepository;
50 import org.apache.archiva.repository.RemoteRepositoryContent;
51 import org.apache.archiva.repository.RepositoryType;
52 import org.apache.archiva.repository.content.Artifact;
53 import org.apache.archiva.repository.content.ItemSelector;
54 import org.apache.archiva.repository.content.base.ArchivaItemSelector;
55 import org.apache.archiva.repository.metadata.base.MetadataTools;
56 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
57 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
58 import org.apache.archiva.repository.storage.fs.FsStorageUtil;
59 import org.apache.archiva.repository.storage.StorageAsset;
60 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
61 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
62 import org.apache.commons.collections4.CollectionUtils;
63 import org.apache.commons.lang3.StringUtils;
64 import org.apache.commons.lang3.SystemUtils;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67 import org.slf4j.MarkerFactory;
69 import javax.annotation.PostConstruct;
70 import javax.inject.Inject;
71 import javax.inject.Named;
72 import java.io.IOException;
73 import java.net.MalformedURLException;
74 import java.nio.file.Files;
75 import java.nio.file.Path;
76 import java.nio.file.StandardCopyOption;
77 import java.util.ArrayList;
78 import java.util.Collections;
79 import java.util.HashMap;
80 import java.util.LinkedHashMap;
81 import java.util.List;
83 import java.util.Properties;
84 import java.util.concurrent.ConcurrentHashMap;
85 import java.util.concurrent.ConcurrentMap;
87 public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
89 protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
91 protected UrlFailureCache urlFailureCache;
94 @Named(value = "metadataTools#default")
95 private MetadataTools metadataTools;
97 private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>( );
98 private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>( );
99 private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>( );
100 private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
103 @Named(value = "archivaTaskScheduler#repository")
104 private ArchivaTaskScheduler<RepositoryTask> scheduler;
107 private ArchivaConfiguration archivaConfiguration;
110 @Named(value = "fileLockManager#default")
111 private FileLockManager fileLockManager;
113 private Map<String, NetworkProxy> networkProxyMap = new ConcurrentHashMap<>();
114 private List<ChecksumAlgorithm> checksumAlgorithms;
117 public void initialize()
119 checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
122 private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
123 String targetRepository,
124 List<ProxyConnectorRuleConfiguration> all )
126 List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations = new ArrayList<>();
128 for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : all )
130 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectorRuleConfiguration.getProxyConnectors() )
132 if ( StringUtils.equals( sourceRepository, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
133 targetRepository, proxyConnector.getTargetRepoId() ) )
135 proxyConnectorRuleConfigurations.add( proxyConnectorRuleConfiguration );
140 return proxyConnectorRuleConfigurations;
146 public StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
147 throws ProxyDownloadException
149 StorageAsset localFile = null;
150 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
153 localFile = toLocalFile( repository, artifact );
155 catch ( LayoutException e )
157 previousExceptions.put( "LayoutException", e );
158 throw new ProxyDownloadException( "Could not convert to BasicRepositoryContentLayout " + e.getMessage( ), previousExceptions);
161 Properties requestProperties = new Properties();
162 requestProperties.setProperty( "filetype", "artifact" );
163 requestProperties.setProperty( "version", artifact.getVersion() );
164 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
166 List<ProxyConnector> connectors = getProxyConnectors( repository );
167 for ( ProxyConnector connector : connectors )
169 if ( !connector.isEnabled() )
174 RemoteRepository targetRepository = connector.getTargetRepository();
175 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
177 String targetPath = targetRepository.getContent().toPath( artifact );
179 if ( SystemUtils.IS_OS_WINDOWS )
181 // toPath use system PATH_SEPARATOR so on windows url are \ which doesn't work very well :-)
182 targetPath = PathUtil.separatorsToUnix( targetPath );
187 StorageAsset downloadedFile =
188 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
191 if ( fileExists(downloadedFile) )
193 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
194 return downloadedFile;
197 catch ( NotFoundException e )
199 log.debug( "Artifact {} not found on repository \"{}\".", Keys.toKey( artifact ),
200 targetRepository.getId() );
202 catch ( NotModifiedException e )
204 log.debug( "Artifact {} not updated on repository \"{}\".", Keys.toKey( artifact ),
205 targetRepository.getId() );
207 catch ( ProxyException e )
209 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact,
210 targetRepository.getContent(), localFile, e, previousExceptions );
214 if ( !previousExceptions.isEmpty() )
216 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
217 previousExceptions );
220 log.debug( "Exhausted all target repositories, artifact {} not found.", Keys.toKey( artifact ) );
226 public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
228 StorageAsset localFile = repository.getAsset( path );
230 // no update policies for these paths
231 if ( localFile.exists() )
236 Properties requestProperties = new Properties();
237 requestProperties.setProperty( "filetype", "resource" );
238 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
240 List<ProxyConnector> connectors = getProxyConnectors( repository );
241 for ( ProxyConnector connector : connectors )
243 if ( !connector.isEnabled() )
248 RemoteRepository targetRepository = connector.getTargetRepository();
249 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
251 String targetPath = path;
255 StorageAsset downloadedFile =
256 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
259 if ( fileExists( downloadedFile ) )
261 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
262 return downloadedFile;
265 catch ( NotFoundException e )
267 log.debug( "Resource {} not found on repository \"{}\".", path,
268 targetRepository.getId() );
270 catch ( NotModifiedException e )
272 log.debug( "Resource {} not updated on repository \"{}\".", path,
273 targetRepository.getId() );
275 catch ( ProxyException e )
278 "Transfer error from repository {} for resource {}, continuing to next repository. Error message: {}",
279 targetRepository.getId(), path, e.getMessage() );
280 log.debug( MarkerFactory.getDetachedMarker( "transfer.error" ),
281 "Transfer error from repository \"{}"
282 + "\" for resource {}, continuing to next repository. Error message: {}",
283 targetRepository.getId(), path, e.getMessage(), e );
288 log.debug( "Exhausted all target repositories, resource {} not found.", path );
294 public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String rawLogicalPath )
297 if (rawLogicalPath.startsWith( "/" )){
298 logicalPath = rawLogicalPath.substring( 1 );
300 logicalPath = rawLogicalPath;
302 StorageAsset localFile = repository.getAsset( logicalPath );
304 Properties requestProperties = new Properties();
305 requestProperties.setProperty( "filetype", "metadata" );
306 boolean metadataNeedsUpdating = false;
307 long originalTimestamp = getLastModified( localFile );
309 List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
310 for ( ProxyConnector connector : connectors )
312 if ( !connector.isEnabled() )
317 RemoteRepository targetRepository = connector.getTargetRepository();
319 StorageAsset localRepoFile = toLocalRepoFile( repository, targetRepository.getContent(), logicalPath );
320 long originalMetadataTimestamp = getLastModified( localRepoFile );
324 transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
327 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
329 metadataNeedsUpdating = true;
332 catch ( NotFoundException e )
335 log.debug( "Metadata {} not found on remote repository '{}'.", logicalPath,
336 targetRepository.getId(), e );
339 catch ( NotModifiedException e )
342 log.debug( "Metadata {} not updated on remote repository '{}'.", logicalPath,
343 targetRepository.getId(), e );
346 catch ( ProxyException e )
349 "Transfer error from repository {} for versioned Metadata {}, continuing to next repository. Error message: {}",
350 targetRepository.getId(), logicalPath, e.getMessage() );
351 log.debug( "Full stack trace", e );
355 if ( hasBeenUpdated( localFile, originalTimestamp ) )
357 metadataNeedsUpdating = true;
360 if ( metadataNeedsUpdating || !localFile.exists())
364 metadataTools.updateMetadata( repository.getContent(), logicalPath );
366 catch ( RepositoryMetadataException e )
368 log.warn( "Unable to update metadata {}:{}", localFile.getPath(), e.getMessage(), e );
373 if ( fileExists( localFile ) )
375 return new ProxyFetchResult( localFile, metadataNeedsUpdating );
378 return new ProxyFetchResult( null, false );
381 private long getLastModified(StorageAsset file )
383 if ( !file.exists() || file.isContainer() )
388 return file.getModificationTime().toEpochMilli();
391 private boolean hasBeenUpdated(StorageAsset file, long originalLastModified )
393 if ( !file.exists() || file.isContainer() )
398 long currentLastModified = getLastModified( file );
399 return ( currentLastModified > originalLastModified );
402 private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
405 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
406 return repository.getAsset( repoPath );
410 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
414 public boolean hasProxies( ManagedRepository repository )
416 synchronized ( this.proxyConnectorMap )
418 return this.proxyConnectorMap.containsKey( repository.getId() );
422 private StorageAsset toLocalFile(ManagedRepository repository, ArtifactReference artifact ) throws LayoutException
424 ItemSelector selector = ArchivaItemSelector.builder( )
425 .withNamespace( artifact.getGroupId( ) )
426 .withProjectId( artifact.getArtifactId( ) )
427 .withArtifactId( artifact.getArtifactId( ) )
428 .withArtifactVersion( artifact.getVersion() )
429 .withVersion( artifact.getProjectVersion( ) )
430 .withType( artifact.getType( ) ).build();
431 Artifact repoArtifact = repository.getContent( ).getLayout( BaseRepositoryContentLayout.class ).getArtifact( selector );
432 return repoArtifact.getAsset( );
436 * Simple method to test if the file exists on the local disk.
438 * @param file the file to test. (may be null)
439 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
441 private boolean fileExists( StorageAsset file )
453 return !file.isContainer();
457 * Perform the transfer of the file.
459 * @param connector the connector configuration to use.
460 * @param remoteRepository the remote repository get the resource from.
461 * @param remotePath the path in the remote repository to the resource to get.
462 * @param repository the managed repository that will hold the file
463 * @param resource the path relative to the repository storage where the file should be downloaded to
464 * @param requestProperties the request properties to utilize for policy handling.
465 * @param executeConsumers whether to execute the consumers after proxying
466 * @return the local file that was downloaded, or null if not downloaded.
467 * @throws NotFoundException if the file was not found on the remote repository.
468 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, but
469 * the remote resource is not newer than the local File.
470 * @throws ProxyException if transfer was unsuccessful.
472 protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
473 ManagedRepository repository, StorageAsset resource, Properties requestProperties,
474 boolean executeConsumers )
475 throws ProxyException, NotModifiedException
480 url = remoteRepository.getLocation().toURL().toString();
482 catch ( MalformedURLException e )
484 throw new ProxyException( e.getMessage(), e );
486 if ( !url.endsWith( "/" ) )
490 if (remotePath.startsWith( "/" )) {
491 url = url + remotePath.substring( 1 );
493 url = url + remotePath;
495 requestProperties.setProperty( "url", url );
497 // Is a whitelist defined?
498 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
500 // Path must belong to whitelist.
501 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
503 log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
504 remotePath, remoteRepository.getId() );
509 // Is target path part of blacklist?
510 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
512 log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
513 remoteRepository.getId() );
517 // Handle pre-download policy
520 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, resource );
522 catch ( PolicyViolationException e )
524 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
525 if ( resource.exists() )
527 log.debug( "{} : using already present local file.", emsg );
535 Path workingDirectory = createWorkingDirectory( repository );
536 FilesystemStorage tmpStorage = null;
539 tmpStorage = new FilesystemStorage( workingDirectory, fileLockManager );
541 catch ( IOException e )
543 throw new ProxyException( "Could not create tmp storage" );
545 StorageAsset tmpResource = tmpStorage.getAsset( resource.getName( ) );
546 StorageAsset[] tmpChecksumFiles = new StorageAsset[checksumAlgorithms.size()];
547 for(int i=0; i<checksumAlgorithms.size(); i++) {
548 ChecksumAlgorithm alg = checksumAlgorithms.get( i );
549 tmpChecksumFiles[i] = tmpStorage.getAsset( resource.getName() + "." + alg.getDefaultExtension() );
555 transferResources( connector, remoteRepository, tmpResource,tmpChecksumFiles , url, remotePath,
556 resource, workingDirectory, repository );
558 // Handle post-download policies.
561 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, tmpResource );
563 catch ( PolicyViolationException e )
565 log.warn( "Transfer invalidated from {} : {}", url, e.getMessage() );
566 executeConsumers = false;
567 if ( !fileExists( tmpResource ) )
573 if ( resource != null )
575 synchronized ( resource.getPath().intern() )
577 StorageAsset directory = resource.getParent();
578 for (int i=0; i<tmpChecksumFiles.length; i++) {
579 moveFileIfExists( tmpChecksumFiles[i], directory );
581 moveFileIfExists( tmpResource, directory );
587 org.apache.archiva.common.utils.FileUtils.deleteQuietly( workingDirectory );
590 if ( executeConsumers )
592 // Just-in-time update of the index and database by executing the consumers for this artifact
593 //consumers.executeConsumers( connector.getSourceRepository().getRepository(), resource );
594 queueRepositoryTask( connector.getSourceRepository().getId(), resource );
600 protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
601 StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
602 ManagedRepository repository ) throws ProxyException;
604 private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
606 RepositoryTask task = new RepositoryTask();
607 task.setRepositoryId( repositoryId );
608 task.setResourceFile( localFile );
609 task.setUpdateRelatedArtifacts( true );
610 task.setScanAll( true );
614 scheduler.queueTask( task );
616 catch ( TaskQueueException e )
618 log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
619 + "'].", localFile.getName() );
624 * Moves the file into repository location if it exists
626 * @param fileToMove this could be either the main artifact, sha1 or md5 checksum file.
627 * @param directory directory to write files to
629 private void moveFileIfExists( StorageAsset fileToMove, StorageAsset directory )
630 throws ProxyException
632 if ( fileToMove != null && fileToMove.exists() )
634 StorageAsset newLocation = directory.getStorage().getAsset( directory.getPath()+ "/" + fileToMove.getName());
635 moveTempToTarget( fileToMove, newLocation );
640 * Apply the policies.
642 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
643 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy
645 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)}
647 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
648 * @throws PolicyViolationException
650 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
651 Properties request, StorageAsset localFile )
652 throws PolicyViolationException
654 for ( Map.Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
656 // olamy with spring rolehint is now downloadPolicy#hint
657 // so substring after last # to get the hint as with plexus
658 String key = entry.getValue( ).getId( );
659 DownloadPolicy policy = entry.getValue();
660 PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
662 log.debug( "Applying [{}] policy with [{}]", key, option );
665 policy.applyPolicy( option, request, localFile );
667 catch ( PolicyConfigurationException e )
669 log.error( e.getMessage(), e );
674 private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
675 Properties request, ArtifactReference artifact, RemoteRepositoryContent content,
676 StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
677 throws ProxyDownloadException
679 boolean process = true;
680 for ( Map.Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() )
683 // olamy with spring rolehint is now downloadPolicy#hint
684 // so substring after last # to get the hint as with plexus
685 String key = entry.getValue( ).getId( );
686 DownloadErrorPolicy policy = entry.getValue();
687 PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
689 log.debug( "Applying [{}] policy with [{}]", key, option );
692 // all policies must approve the exception, any can cancel
693 process = policy.applyPolicy( option, request, localFile, exception, previousExceptions );
699 catch ( PolicyConfigurationException e )
701 log.error( e.getMessage(), e );
707 // if the exception was queued, don't throw it
708 if ( !previousExceptions.containsKey( content.getId() ) )
710 throw new ProxyDownloadException(
711 "An error occurred in downloading from the remote repository, and the policy is to fail immediately",
712 content.getId(), exception );
717 // if the exception was queued, but cancelled, remove it
718 previousExceptions.remove( content.getId() );
722 "Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
723 content.getRepository().getId(), Keys.toKey( artifact ), exception.getMessage() );
724 log.debug( "Full stack trace", exception );
728 * Creates a working directory
731 * @return file location of working directory
733 private Path createWorkingDirectory( ManagedRepository repository )
737 return Files.createTempDirectory( "temp" );
739 catch ( IOException e )
741 throw new RuntimeException( e.getMessage(), e );
747 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles its
750 * @param temp The completed download file
751 * @param target The final location of the downloaded file
752 * @throws ProxyException when the temp file cannot replace the target file
754 private void moveTempToTarget( StorageAsset temp, StorageAsset target )
755 throws ProxyException
760 org.apache.archiva.repository.storage.util.StorageUtil.moveAsset( temp, target, true , StandardCopyOption.REPLACE_EXISTING);
762 catch ( IOException e )
764 log.error( "Move failed from {} to {}, trying copy.", temp, target );
767 FsStorageUtil.copyAsset( temp, target, true );
769 temp.getStorage( ).removeAsset( temp );
772 catch ( IOException ex )
774 log.error("Copy failed from {} to {}: ({}) {}", temp, target, e.getClass(), e.getMessage());
775 throw new ProxyException("Could not move temp file "+temp.getPath()+" to target "+target.getPath()+": ("+e.getClass()+") "+e.getMessage(), e);
781 * Tests whitelist and blacklist patterns against path.
783 * @param path the path to test.
784 * @param patterns the list of patterns to check.
785 * @return true if the path matches at least 1 pattern in the provided patterns list.
787 private boolean matchesPattern( String path, List<String> patterns )
789 if ( CollectionUtils.isEmpty( patterns ) )
794 if ( !path.startsWith( "/" ) )
799 for ( String pattern : patterns )
801 if ( !pattern.startsWith( "/" ) )
803 pattern = "/" + pattern;
806 if ( PathUtil.matchPath( pattern, path, false ) )
816 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
820 public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
823 if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
825 return Collections.emptyList();
827 List<ProxyConnector> ret = new ArrayList<>( this.proxyConnectorMap.get( repository.getId() ) );
829 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
835 protected String addParameters(String path, RemoteRepository remoteRepository )
837 if ( remoteRepository.getExtraParameters().isEmpty() )
842 boolean question = false;
844 StringBuilder res = new StringBuilder( path == null ? "" : path );
846 for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters().entrySet() )
850 res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() );
854 return res.toString();
857 public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
859 this.archivaConfiguration = archivaConfiguration;
862 public MetadataTools getMetadataTools()
864 return metadataTools;
867 public void setMetadataTools(MetadataTools metadataTools )
869 this.metadataTools = metadataTools;
872 public UrlFailureCache getUrlFailureCache()
874 return urlFailureCache;
877 public void setUrlFailureCache(UrlFailureCache urlFailureCache )
879 this.urlFailureCache = urlFailureCache;
882 public Map<String, PreDownloadPolicy> getPreDownloadPolicies()
884 return preDownloadPolicies;
887 public void setPreDownloadPolicies(Map<String, PreDownloadPolicy> preDownloadPolicies )
889 this.preDownloadPolicies = preDownloadPolicies;
892 public Map<String, PostDownloadPolicy> getPostDownloadPolicies()
894 return postDownloadPolicies;
897 public void setPostDownloadPolicies(Map<String, PostDownloadPolicy> postDownloadPolicies )
899 this.postDownloadPolicies = postDownloadPolicies;
902 public Map<String, DownloadErrorPolicy> getDownloadErrorPolicies()
904 return downloadErrorPolicies;
907 public void setDownloadErrorPolicies(Map<String, DownloadErrorPolicy> downloadErrorPolicies )
909 this.downloadErrorPolicies = downloadErrorPolicies;
913 public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
914 this.networkProxyMap.clear();
915 this.networkProxyMap.putAll( networkProxies );
919 public NetworkProxy getNetworkProxy(String id) {
920 return this.networkProxyMap.get(id);
924 public Map<String, NetworkProxy> getNetworkProxies() {
925 return this.networkProxyMap;
929 public abstract List<RepositoryType> supports();
932 public void setPolicies( List<Policy> policyList )
934 preDownloadPolicies.clear();
935 postDownloadPolicies.clear();
936 downloadErrorPolicies.clear();
937 for (Policy policy : policyList) {
942 void addPolicy(PreDownloadPolicy policy) {
943 preDownloadPolicies.put( policy.getId( ), policy );
946 void addPolicy(PostDownloadPolicy policy) {
947 postDownloadPolicies.put( policy.getId( ), policy );
949 void addPolicy(DownloadErrorPolicy policy) {
950 downloadErrorPolicies.put( policy.getId( ), policy );
954 public void addPolicy( Policy policy )
956 if (policy instanceof PreDownloadPolicy) {
957 addPolicy( (PreDownloadPolicy)policy );
958 } else if (policy instanceof PostDownloadPolicy) {
959 addPolicy( (PostDownloadPolicy) policy );
960 } else if (policy instanceof DownloadErrorPolicy) {
961 addPolicy( (DownloadErrorPolicy) policy );
963 log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
968 public void removePolicy( Policy policy )
970 final String id = policy.getId();
971 if (preDownloadPolicies.containsKey( id )) {
972 preDownloadPolicies.remove( id );
973 } else if (postDownloadPolicies.containsKey( id )) {
974 postDownloadPolicies.remove( id );
975 } else if (downloadErrorPolicies.containsKey( id )) {
976 downloadErrorPolicies.remove( id );
981 public void addProxyConnector( ProxyConnector connector )
983 final String sourceId = connector.getSourceRepository( ).getId( );
984 List<ProxyConnector> connectors;
985 if (proxyConnectorMap.containsKey( sourceId )) {
986 connectors = proxyConnectorMap.get( sourceId );
988 connectors = new ArrayList<>( );
989 proxyConnectorMap.put( sourceId, connectors );
991 connectors.add( connector );
995 public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
997 proxyConnectorMap.clear();
998 for ( ProxyConnector connector : proxyConnectors )
1000 addProxyConnector( connector );