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.metadata.base.MetadataTools;
53 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
54 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
55 import org.apache.archiva.repository.storage.fs.FsStorageUtil;
56 import org.apache.archiva.repository.storage.StorageAsset;
57 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
58 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
59 import org.apache.commons.collections4.CollectionUtils;
60 import org.apache.commons.lang3.StringUtils;
61 import org.apache.commons.lang3.SystemUtils;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64 import org.slf4j.MarkerFactory;
66 import javax.annotation.PostConstruct;
67 import javax.inject.Inject;
68 import javax.inject.Named;
69 import java.io.IOException;
70 import java.net.MalformedURLException;
71 import java.nio.file.Files;
72 import java.nio.file.Path;
73 import java.nio.file.StandardCopyOption;
74 import java.util.ArrayList;
75 import java.util.Collections;
76 import java.util.HashMap;
77 import java.util.LinkedHashMap;
78 import java.util.List;
80 import java.util.Properties;
81 import java.util.concurrent.ConcurrentHashMap;
82 import java.util.concurrent.ConcurrentMap;
84 public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
86 protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
88 protected UrlFailureCache urlFailureCache;
91 @Named(value = "metadataTools#default")
92 private MetadataTools metadataTools;
94 private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>( );
95 private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>( );
96 private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>( );
97 private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
100 @Named(value = "archivaTaskScheduler#repository")
101 private ArchivaTaskScheduler<RepositoryTask> scheduler;
104 private ArchivaConfiguration archivaConfiguration;
107 @Named(value = "fileLockManager#default")
108 private FileLockManager fileLockManager;
110 private Map<String, NetworkProxy> networkProxyMap = new ConcurrentHashMap<>();
111 private List<ChecksumAlgorithm> checksumAlgorithms;
114 public void initialize()
116 checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
119 private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
120 String targetRepository,
121 List<ProxyConnectorRuleConfiguration> all )
123 List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations = new ArrayList<>();
125 for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : all )
127 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectorRuleConfiguration.getProxyConnectors() )
129 if ( StringUtils.equals( sourceRepository, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
130 targetRepository, proxyConnector.getTargetRepoId() ) )
132 proxyConnectorRuleConfigurations.add( proxyConnectorRuleConfiguration );
137 return proxyConnectorRuleConfigurations;
143 public StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
144 throws ProxyDownloadException
146 StorageAsset localFile = null;
147 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
150 localFile = toLocalFile( repository, artifact );
152 catch ( LayoutException e )
154 previousExceptions.put( "LayoutException", e );
155 throw new ProxyDownloadException( "Could not convert to BasicRepositoryContentLayout " + e.getMessage( ), previousExceptions);
158 Properties requestProperties = new Properties();
159 requestProperties.setProperty( "filetype", "artifact" );
160 requestProperties.setProperty( "version", artifact.getVersion() );
161 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
163 List<ProxyConnector> connectors = getProxyConnectors( repository );
164 for ( ProxyConnector connector : connectors )
166 if ( !connector.isEnabled() )
171 RemoteRepository targetRepository = connector.getTargetRepository();
172 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
174 String targetPath = targetRepository.getContent().toPath( artifact );
176 if ( SystemUtils.IS_OS_WINDOWS )
178 // toPath use system PATH_SEPARATOR so on windows url are \ which doesn't work very well :-)
179 targetPath = PathUtil.separatorsToUnix( targetPath );
184 StorageAsset downloadedFile =
185 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
188 if ( fileExists(downloadedFile) )
190 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
191 return downloadedFile;
194 catch ( NotFoundException e )
196 log.debug( "Artifact {} not found on repository \"{}\".", Keys.toKey( artifact ),
197 targetRepository.getId() );
199 catch ( NotModifiedException e )
201 log.debug( "Artifact {} not updated on repository \"{}\".", Keys.toKey( artifact ),
202 targetRepository.getId() );
204 catch ( ProxyException e )
206 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact,
207 targetRepository.getContent(), localFile, e, previousExceptions );
211 if ( !previousExceptions.isEmpty() )
213 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
214 previousExceptions );
217 log.debug( "Exhausted all target repositories, artifact {} not found.", Keys.toKey( artifact ) );
223 public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
225 StorageAsset localFile = repository.getAsset( path );
227 // no update policies for these paths
228 if ( localFile.exists() )
233 Properties requestProperties = new Properties();
234 requestProperties.setProperty( "filetype", "resource" );
235 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
237 List<ProxyConnector> connectors = getProxyConnectors( repository );
238 for ( ProxyConnector connector : connectors )
240 if ( !connector.isEnabled() )
245 RemoteRepository targetRepository = connector.getTargetRepository();
246 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
248 String targetPath = path;
252 StorageAsset downloadedFile =
253 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
256 if ( fileExists( downloadedFile ) )
258 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
259 return downloadedFile;
262 catch ( NotFoundException e )
264 log.debug( "Resource {} not found on repository \"{}\".", path,
265 targetRepository.getId() );
267 catch ( NotModifiedException e )
269 log.debug( "Resource {} not updated on repository \"{}\".", path,
270 targetRepository.getId() );
272 catch ( ProxyException e )
275 "Transfer error from repository {} for resource {}, continuing to next repository. Error message: {}",
276 targetRepository.getId(), path, e.getMessage() );
277 log.debug( MarkerFactory.getDetachedMarker( "transfer.error" ),
278 "Transfer error from repository \"{}"
279 + "\" for resource {}, continuing to next repository. Error message: {}",
280 targetRepository.getId(), path, e.getMessage(), e );
285 log.debug( "Exhausted all target repositories, resource {} not found.", path );
291 public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String rawLogicalPath )
294 if (rawLogicalPath.startsWith( "/" )){
295 logicalPath = rawLogicalPath.substring( 1 );
297 logicalPath = rawLogicalPath;
299 StorageAsset localFile = repository.getAsset( logicalPath );
301 Properties requestProperties = new Properties();
302 requestProperties.setProperty( "filetype", "metadata" );
303 boolean metadataNeedsUpdating = false;
304 long originalTimestamp = getLastModified( localFile );
306 List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
307 for ( ProxyConnector connector : connectors )
309 if ( !connector.isEnabled() )
314 RemoteRepository targetRepository = connector.getTargetRepository();
316 StorageAsset localRepoFile = toLocalRepoFile( repository, targetRepository.getContent(), logicalPath );
317 long originalMetadataTimestamp = getLastModified( localRepoFile );
321 transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
324 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
326 metadataNeedsUpdating = true;
329 catch ( NotFoundException e )
332 log.debug( "Metadata {} not found on remote repository '{}'.", logicalPath,
333 targetRepository.getId(), e );
336 catch ( NotModifiedException e )
339 log.debug( "Metadata {} not updated on remote repository '{}'.", logicalPath,
340 targetRepository.getId(), e );
343 catch ( ProxyException e )
346 "Transfer error from repository {} for versioned Metadata {}, continuing to next repository. Error message: {}",
347 targetRepository.getId(), logicalPath, e.getMessage() );
348 log.debug( "Full stack trace", e );
352 if ( hasBeenUpdated( localFile, originalTimestamp ) )
354 metadataNeedsUpdating = true;
357 if ( metadataNeedsUpdating || !localFile.exists())
361 metadataTools.updateMetadata( repository.getContent(), logicalPath );
363 catch ( RepositoryMetadataException e )
365 log.warn( "Unable to update metadata {}:{}", localFile.getPath(), e.getMessage(), e );
370 if ( fileExists( localFile ) )
372 return new ProxyFetchResult( localFile, metadataNeedsUpdating );
375 return new ProxyFetchResult( null, false );
378 private long getLastModified(StorageAsset file )
380 if ( !file.exists() || file.isContainer() )
385 return file.getModificationTime().toEpochMilli();
388 private boolean hasBeenUpdated(StorageAsset file, long originalLastModified )
390 if ( !file.exists() || file.isContainer() )
395 long currentLastModified = getLastModified( file );
396 return ( currentLastModified > originalLastModified );
399 private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
402 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
403 return repository.getAsset( repoPath );
407 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
411 public boolean hasProxies( ManagedRepository repository )
413 synchronized ( this.proxyConnectorMap )
415 return this.proxyConnectorMap.containsKey( repository.getId() );
419 private StorageAsset toLocalFile(ManagedRepository repository, ArtifactReference artifact ) throws LayoutException
421 return repository.getContent().getLayout( BaseRepositoryContentLayout.class ).toFile( artifact );
425 * Simple method to test if the file exists on the local disk.
427 * @param file the file to test. (may be null)
428 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
430 private boolean fileExists( StorageAsset file )
442 return !file.isContainer();
446 * Perform the transfer of the file.
448 * @param connector the connector configuration to use.
449 * @param remoteRepository the remote repository get the resource from.
450 * @param remotePath the path in the remote repository to the resource to get.
451 * @param repository the managed repository that will hold the file
452 * @param resource the path relative to the repository storage where the file should be downloaded to
453 * @param requestProperties the request properties to utilize for policy handling.
454 * @param executeConsumers whether to execute the consumers after proxying
455 * @return the local file that was downloaded, or null if not downloaded.
456 * @throws NotFoundException if the file was not found on the remote repository.
457 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, but
458 * the remote resource is not newer than the local File.
459 * @throws ProxyException if transfer was unsuccessful.
461 protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
462 ManagedRepository repository, StorageAsset resource, Properties requestProperties,
463 boolean executeConsumers )
464 throws ProxyException, NotModifiedException
469 url = remoteRepository.getLocation().toURL().toString();
471 catch ( MalformedURLException e )
473 throw new ProxyException( e.getMessage(), e );
475 if ( !url.endsWith( "/" ) )
479 if (remotePath.startsWith( "/" )) {
480 url = url + remotePath.substring( 1 );
482 url = url + remotePath;
484 requestProperties.setProperty( "url", url );
486 // Is a whitelist defined?
487 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
489 // Path must belong to whitelist.
490 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
492 log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
493 remotePath, remoteRepository.getId() );
498 // Is target path part of blacklist?
499 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
501 log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
502 remoteRepository.getId() );
506 // Handle pre-download policy
509 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, resource );
511 catch ( PolicyViolationException e )
513 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
514 if ( resource.exists() )
516 log.debug( "{} : using already present local file.", emsg );
524 Path workingDirectory = createWorkingDirectory( repository );
525 FilesystemStorage tmpStorage = null;
528 tmpStorage = new FilesystemStorage( workingDirectory, fileLockManager );
530 catch ( IOException e )
532 throw new ProxyException( "Could not create tmp storage" );
534 StorageAsset tmpResource = tmpStorage.getAsset( resource.getName( ) );
535 StorageAsset[] tmpChecksumFiles = new StorageAsset[checksumAlgorithms.size()];
536 for(int i=0; i<checksumAlgorithms.size(); i++) {
537 ChecksumAlgorithm alg = checksumAlgorithms.get( i );
538 tmpChecksumFiles[i] = tmpStorage.getAsset( resource.getName() + "." + alg.getDefaultExtension() );
544 transferResources( connector, remoteRepository, tmpResource,tmpChecksumFiles , url, remotePath,
545 resource, workingDirectory, repository );
547 // Handle post-download policies.
550 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, tmpResource );
552 catch ( PolicyViolationException e )
554 log.warn( "Transfer invalidated from {} : {}", url, e.getMessage() );
555 executeConsumers = false;
556 if ( !fileExists( tmpResource ) )
562 if ( resource != null )
564 synchronized ( resource.getPath().intern() )
566 StorageAsset directory = resource.getParent();
567 for (int i=0; i<tmpChecksumFiles.length; i++) {
568 moveFileIfExists( tmpChecksumFiles[i], directory );
570 moveFileIfExists( tmpResource, directory );
576 org.apache.archiva.common.utils.FileUtils.deleteQuietly( workingDirectory );
579 if ( executeConsumers )
581 // Just-in-time update of the index and database by executing the consumers for this artifact
582 //consumers.executeConsumers( connector.getSourceRepository().getRepository(), resource );
583 queueRepositoryTask( connector.getSourceRepository().getId(), resource );
589 protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
590 StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
591 ManagedRepository repository ) throws ProxyException;
593 private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
595 RepositoryTask task = new RepositoryTask();
596 task.setRepositoryId( repositoryId );
597 task.setResourceFile( localFile );
598 task.setUpdateRelatedArtifacts( true );
599 task.setScanAll( true );
603 scheduler.queueTask( task );
605 catch ( TaskQueueException e )
607 log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
608 + "'].", localFile.getName() );
613 * Moves the file into repository location if it exists
615 * @param fileToMove this could be either the main artifact, sha1 or md5 checksum file.
616 * @param directory directory to write files to
618 private void moveFileIfExists( StorageAsset fileToMove, StorageAsset directory )
619 throws ProxyException
621 if ( fileToMove != null && fileToMove.exists() )
623 StorageAsset newLocation = directory.getStorage().getAsset( directory.getPath()+ "/" + fileToMove.getName());
624 moveTempToTarget( fileToMove, newLocation );
629 * Apply the policies.
631 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
632 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy
634 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)}
636 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
637 * @throws PolicyViolationException
639 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
640 Properties request, StorageAsset localFile )
641 throws PolicyViolationException
643 for ( Map.Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
645 // olamy with spring rolehint is now downloadPolicy#hint
646 // so substring after last # to get the hint as with plexus
647 String key = entry.getValue( ).getId( );
648 DownloadPolicy policy = entry.getValue();
649 PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
651 log.debug( "Applying [{}] policy with [{}]", key, option );
654 policy.applyPolicy( option, request, localFile );
656 catch ( PolicyConfigurationException e )
658 log.error( e.getMessage(), e );
663 private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
664 Properties request, ArtifactReference artifact, RemoteRepositoryContent content,
665 StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
666 throws ProxyDownloadException
668 boolean process = true;
669 for ( Map.Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() )
672 // olamy with spring rolehint is now downloadPolicy#hint
673 // so substring after last # to get the hint as with plexus
674 String key = entry.getValue( ).getId( );
675 DownloadErrorPolicy policy = entry.getValue();
676 PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
678 log.debug( "Applying [{}] policy with [{}]", key, option );
681 // all policies must approve the exception, any can cancel
682 process = policy.applyPolicy( option, request, localFile, exception, previousExceptions );
688 catch ( PolicyConfigurationException e )
690 log.error( e.getMessage(), e );
696 // if the exception was queued, don't throw it
697 if ( !previousExceptions.containsKey( content.getId() ) )
699 throw new ProxyDownloadException(
700 "An error occurred in downloading from the remote repository, and the policy is to fail immediately",
701 content.getId(), exception );
706 // if the exception was queued, but cancelled, remove it
707 previousExceptions.remove( content.getId() );
711 "Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
712 content.getRepository().getId(), Keys.toKey( artifact ), exception.getMessage() );
713 log.debug( "Full stack trace", exception );
717 * Creates a working directory
720 * @return file location of working directory
722 private Path createWorkingDirectory( ManagedRepository repository )
726 return Files.createTempDirectory( "temp" );
728 catch ( IOException e )
730 throw new RuntimeException( e.getMessage(), e );
736 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles its
739 * @param temp The completed download file
740 * @param target The final location of the downloaded file
741 * @throws ProxyException when the temp file cannot replace the target file
743 private void moveTempToTarget( StorageAsset temp, StorageAsset target )
744 throws ProxyException
749 org.apache.archiva.repository.storage.util.StorageUtil.moveAsset( temp, target, true , StandardCopyOption.REPLACE_EXISTING);
751 catch ( IOException e )
753 log.error( "Move failed from {} to {}, trying copy.", temp, target );
756 FsStorageUtil.copyAsset( temp, target, true );
758 temp.getStorage( ).removeAsset( temp );
761 catch ( IOException ex )
763 log.error("Copy failed from {} to {}: ({}) {}", temp, target, e.getClass(), e.getMessage());
764 throw new ProxyException("Could not move temp file "+temp.getPath()+" to target "+target.getPath()+": ("+e.getClass()+") "+e.getMessage(), e);
770 * Tests whitelist and blacklist patterns against path.
772 * @param path the path to test.
773 * @param patterns the list of patterns to check.
774 * @return true if the path matches at least 1 pattern in the provided patterns list.
776 private boolean matchesPattern( String path, List<String> patterns )
778 if ( CollectionUtils.isEmpty( patterns ) )
783 if ( !path.startsWith( "/" ) )
788 for ( String pattern : patterns )
790 if ( !pattern.startsWith( "/" ) )
792 pattern = "/" + pattern;
795 if ( PathUtil.matchPath( pattern, path, false ) )
805 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
809 public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
812 if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
814 return Collections.emptyList();
816 List<ProxyConnector> ret = new ArrayList<>( this.proxyConnectorMap.get( repository.getId() ) );
818 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
824 protected String addParameters(String path, RemoteRepository remoteRepository )
826 if ( remoteRepository.getExtraParameters().isEmpty() )
831 boolean question = false;
833 StringBuilder res = new StringBuilder( path == null ? "" : path );
835 for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters().entrySet() )
839 res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() );
843 return res.toString();
846 public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
848 this.archivaConfiguration = archivaConfiguration;
851 public MetadataTools getMetadataTools()
853 return metadataTools;
856 public void setMetadataTools(MetadataTools metadataTools )
858 this.metadataTools = metadataTools;
861 public UrlFailureCache getUrlFailureCache()
863 return urlFailureCache;
866 public void setUrlFailureCache(UrlFailureCache urlFailureCache )
868 this.urlFailureCache = urlFailureCache;
871 public Map<String, PreDownloadPolicy> getPreDownloadPolicies()
873 return preDownloadPolicies;
876 public void setPreDownloadPolicies(Map<String, PreDownloadPolicy> preDownloadPolicies )
878 this.preDownloadPolicies = preDownloadPolicies;
881 public Map<String, PostDownloadPolicy> getPostDownloadPolicies()
883 return postDownloadPolicies;
886 public void setPostDownloadPolicies(Map<String, PostDownloadPolicy> postDownloadPolicies )
888 this.postDownloadPolicies = postDownloadPolicies;
891 public Map<String, DownloadErrorPolicy> getDownloadErrorPolicies()
893 return downloadErrorPolicies;
896 public void setDownloadErrorPolicies(Map<String, DownloadErrorPolicy> downloadErrorPolicies )
898 this.downloadErrorPolicies = downloadErrorPolicies;
902 public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
903 this.networkProxyMap.clear();
904 this.networkProxyMap.putAll( networkProxies );
908 public NetworkProxy getNetworkProxy(String id) {
909 return this.networkProxyMap.get(id);
913 public Map<String, NetworkProxy> getNetworkProxies() {
914 return this.networkProxyMap;
918 public abstract List<RepositoryType> supports();
921 public void setPolicies( List<Policy> policyList )
923 preDownloadPolicies.clear();
924 postDownloadPolicies.clear();
925 downloadErrorPolicies.clear();
926 for (Policy policy : policyList) {
931 void addPolicy(PreDownloadPolicy policy) {
932 preDownloadPolicies.put( policy.getId( ), policy );
935 void addPolicy(PostDownloadPolicy policy) {
936 postDownloadPolicies.put( policy.getId( ), policy );
938 void addPolicy(DownloadErrorPolicy policy) {
939 downloadErrorPolicies.put( policy.getId( ), policy );
943 public void addPolicy( Policy policy )
945 if (policy instanceof PreDownloadPolicy) {
946 addPolicy( (PreDownloadPolicy)policy );
947 } else if (policy instanceof PostDownloadPolicy) {
948 addPolicy( (PostDownloadPolicy) policy );
949 } else if (policy instanceof DownloadErrorPolicy) {
950 addPolicy( (DownloadErrorPolicy) policy );
952 log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
957 public void removePolicy( Policy policy )
959 final String id = policy.getId();
960 if (preDownloadPolicies.containsKey( id )) {
961 preDownloadPolicies.remove( id );
962 } else if (postDownloadPolicies.containsKey( id )) {
963 postDownloadPolicies.remove( id );
964 } else if (downloadErrorPolicies.containsKey( id )) {
965 downloadErrorPolicies.remove( id );
970 public void addProxyConnector( ProxyConnector connector )
972 final String sourceId = connector.getSourceRepository( ).getId( );
973 List<ProxyConnector> connectors;
974 if (proxyConnectorMap.containsKey( sourceId )) {
975 connectors = proxyConnectorMap.get( sourceId );
977 connectors = new ArrayList<>( );
978 proxyConnectorMap.put( sourceId, connectors );
980 connectors.add( connector );
984 public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
986 proxyConnectorMap.clear();
987 for ( ProxyConnector connector : proxyConnectors )
989 addProxyConnector( connector );