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.configuration.ArchivaConfiguration;
26 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
27 import org.apache.archiva.configuration.ProxyConnectorRuleConfiguration;
28 import org.apache.archiva.model.ArtifactReference;
29 import org.apache.archiva.model.Keys;
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.redback.components.taskqueue.TaskQueueException;
45 import org.apache.archiva.repository.ManagedRepository;
46 import org.apache.archiva.repository.RemoteRepository;
47 import org.apache.archiva.repository.RemoteRepositoryContent;
48 import org.apache.archiva.repository.RepositoryType;
49 import org.apache.archiva.repository.metadata.base.MetadataTools;
50 import org.apache.archiva.repository.metadata.RepositoryMetadataException;
51 import org.apache.archiva.repository.storage.FilesystemStorage;
52 import org.apache.archiva.repository.storage.StorageAsset;
53 import org.apache.archiva.repository.storage.StorageUtil;
54 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
55 import org.apache.archiva.scheduler.repository.model.RepositoryTask;
56 import org.apache.commons.collections4.CollectionUtils;
57 import org.apache.commons.io.FilenameUtils;
58 import org.apache.commons.lang3.StringUtils;
59 import org.apache.commons.lang3.SystemUtils;
60 import org.apache.tools.ant.types.selectors.SelectorUtils;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63 import org.slf4j.MarkerFactory;
65 import javax.annotation.PostConstruct;
66 import javax.inject.Inject;
67 import javax.inject.Named;
68 import java.io.IOException;
69 import java.net.MalformedURLException;
70 import java.nio.file.Files;
71 import java.nio.file.Path;
72 import java.nio.file.StandardCopyOption;
73 import java.util.ArrayList;
74 import java.util.Collections;
75 import java.util.HashMap;
76 import java.util.LinkedHashMap;
77 import java.util.List;
79 import java.util.Properties;
80 import java.util.concurrent.ConcurrentHashMap;
81 import java.util.concurrent.ConcurrentMap;
83 public abstract class DefaultRepositoryProxyHandler implements RepositoryProxyHandler {
85 protected Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyHandler.class );
87 protected UrlFailureCache urlFailureCache;
90 @Named(value = "metadataTools#default")
91 private MetadataTools metadataTools;
93 private Map<String, PreDownloadPolicy> preDownloadPolicies = new HashMap<>( );
94 private Map<String, PostDownloadPolicy> postDownloadPolicies = new HashMap<>( );
95 private Map<String, DownloadErrorPolicy> downloadErrorPolicies = new HashMap<>( );
96 private ConcurrentMap<String, List<ProxyConnector>> proxyConnectorMap = new ConcurrentHashMap<>();
99 @Named(value = "archivaTaskScheduler#repository")
100 private ArchivaTaskScheduler<RepositoryTask> scheduler;
103 private ArchivaConfiguration archivaConfiguration;
106 @Named(value = "fileLockManager#default")
107 private FileLockManager fileLockManager;
109 private Map<String, NetworkProxy> networkProxyMap = new ConcurrentHashMap<>();
110 private List<ChecksumAlgorithm> checksumAlgorithms;
113 public void initialize()
115 checksumAlgorithms = ChecksumUtil.getAlgorithms(archivaConfiguration.getConfiguration().getArchivaRuntimeConfiguration().getChecksumTypes());
118 private List<ProxyConnectorRuleConfiguration> findProxyConnectorRules(String sourceRepository,
119 String targetRepository,
120 List<ProxyConnectorRuleConfiguration> all )
122 List<ProxyConnectorRuleConfiguration> proxyConnectorRuleConfigurations = new ArrayList<>();
124 for ( ProxyConnectorRuleConfiguration proxyConnectorRuleConfiguration : all )
126 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectorRuleConfiguration.getProxyConnectors() )
128 if ( StringUtils.equals( sourceRepository, proxyConnector.getSourceRepoId() ) && StringUtils.equals(
129 targetRepository, proxyConnector.getTargetRepoId() ) )
131 proxyConnectorRuleConfigurations.add( proxyConnectorRuleConfiguration );
136 return proxyConnectorRuleConfigurations;
140 public StorageAsset fetchFromProxies( ManagedRepository repository, ArtifactReference artifact )
141 throws ProxyDownloadException
143 StorageAsset localFile = toLocalFile( repository, artifact );
145 Properties requestProperties = new Properties();
146 requestProperties.setProperty( "filetype", "artifact" );
147 requestProperties.setProperty( "version", artifact.getVersion() );
148 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
150 List<ProxyConnector> connectors = getProxyConnectors( repository );
151 Map<String, Exception> previousExceptions = new LinkedHashMap<>();
152 for ( ProxyConnector connector : connectors )
154 if ( !connector.isEnabled() )
159 RemoteRepository targetRepository = connector.getTargetRepository();
160 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
162 String targetPath = targetRepository.getContent().toPath( artifact );
164 if ( SystemUtils.IS_OS_WINDOWS )
166 // toPath use system PATH_SEPARATOR so on windows url are \ which doesn't work very well :-)
167 targetPath = FilenameUtils.separatorsToUnix( targetPath );
172 StorageAsset downloadedFile =
173 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
176 if ( fileExists(downloadedFile) )
178 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
179 return downloadedFile;
182 catch ( NotFoundException e )
184 log.debug( "Artifact {} not found on repository \"{}\".", Keys.toKey( artifact ),
185 targetRepository.getId() );
187 catch ( NotModifiedException e )
189 log.debug( "Artifact {} not updated on repository \"{}\".", Keys.toKey( artifact ),
190 targetRepository.getId() );
192 catch ( ProxyException e )
194 validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact,
195 targetRepository.getContent(), localFile, e, previousExceptions );
199 if ( !previousExceptions.isEmpty() )
201 throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories",
202 previousExceptions );
205 log.debug( "Exhausted all target repositories, artifact {} not found.", Keys.toKey( artifact ) );
211 public StorageAsset fetchFromProxies( ManagedRepository repository, String path )
213 StorageAsset localFile = repository.getAsset( path );
215 // no update policies for these paths
216 if ( localFile.exists() )
221 Properties requestProperties = new Properties();
222 requestProperties.setProperty( "filetype", "resource" );
223 requestProperties.setProperty( "managedRepositoryId", repository.getId() );
225 List<ProxyConnector> connectors = getProxyConnectors( repository );
226 for ( ProxyConnector connector : connectors )
228 if ( !connector.isEnabled() )
233 RemoteRepository targetRepository = connector.getTargetRepository();
234 requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() );
236 String targetPath = path;
240 StorageAsset downloadedFile =
241 transferFile( connector, targetRepository, targetPath, repository, localFile, requestProperties,
244 if ( fileExists( downloadedFile ) )
246 log.debug( "Successfully transferred: {}", downloadedFile.getPath() );
247 return downloadedFile;
250 catch ( NotFoundException e )
252 log.debug( "Resource {} not found on repository \"{}\".", path,
253 targetRepository.getId() );
255 catch ( NotModifiedException e )
257 log.debug( "Resource {} not updated on repository \"{}\".", path,
258 targetRepository.getId() );
260 catch ( ProxyException e )
263 "Transfer error from repository {} for resource {}, continuing to next repository. Error message: {}",
264 targetRepository.getId(), path, e.getMessage() );
265 log.debug( MarkerFactory.getDetachedMarker( "transfer.error" ),
266 "Transfer error from repository \"{}"
267 + "\" for resource {}, continuing to next repository. Error message: {}",
268 targetRepository.getId(), path, e.getMessage(), e );
273 log.debug( "Exhausted all target repositories, resource {} not found.", path );
279 public ProxyFetchResult fetchMetadataFromProxies( ManagedRepository repository, String logicalPath )
281 StorageAsset localFile = repository.getAsset( logicalPath );
283 Properties requestProperties = new Properties();
284 requestProperties.setProperty( "filetype", "metadata" );
285 boolean metadataNeedsUpdating = false;
286 long originalTimestamp = getLastModified( localFile );
288 List<ProxyConnector> connectors = new ArrayList<>( getProxyConnectors( repository ) );
289 for ( ProxyConnector connector : connectors )
291 if ( !connector.isEnabled() )
296 RemoteRepository targetRepository = connector.getTargetRepository();
298 StorageAsset localRepoFile = toLocalRepoFile( repository, targetRepository.getContent(), logicalPath );
299 long originalMetadataTimestamp = getLastModified( localRepoFile );
303 transferFile( connector, targetRepository, logicalPath, repository, localRepoFile, requestProperties,
306 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
308 metadataNeedsUpdating = true;
311 catch ( NotFoundException e )
314 log.debug( "Metadata {} not found on remote repository '{}'.", logicalPath,
315 targetRepository.getId(), e );
318 catch ( NotModifiedException e )
321 log.debug( "Metadata {} not updated on remote repository '{}'.", logicalPath,
322 targetRepository.getId(), e );
325 catch ( ProxyException e )
328 "Transfer error from repository {} for versioned Metadata {}, continuing to next repository. Error message: {}",
329 targetRepository.getId(), logicalPath, e.getMessage() );
330 log.debug( "Full stack trace", e );
334 if ( hasBeenUpdated( localFile, originalTimestamp ) )
336 metadataNeedsUpdating = true;
339 if ( metadataNeedsUpdating || !localFile.exists())
343 metadataTools.updateMetadata( repository.getContent(), logicalPath );
345 catch ( RepositoryMetadataException e )
347 log.warn( "Unable to update metadata {}:{}", localFile.getPath(), e.getMessage(), e );
352 if ( fileExists( localFile ) )
354 return new ProxyFetchResult( localFile, metadataNeedsUpdating );
357 return new ProxyFetchResult( null, false );
360 private long getLastModified(StorageAsset file )
362 if ( !file.exists() || file.isContainer() )
367 return file.getModificationTime().toEpochMilli();
370 private boolean hasBeenUpdated(StorageAsset file, long originalLastModified )
372 if ( !file.exists() || file.isContainer() )
377 long currentLastModified = getLastModified( file );
378 return ( currentLastModified > originalLastModified );
381 private StorageAsset toLocalRepoFile( ManagedRepository repository, RemoteRepositoryContent targetRepository,
384 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
385 return repository.getAsset( repoPath );
389 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
393 public boolean hasProxies( ManagedRepository repository )
395 synchronized ( this.proxyConnectorMap )
397 return this.proxyConnectorMap.containsKey( repository.getId() );
401 private StorageAsset toLocalFile(ManagedRepository repository, ArtifactReference artifact )
403 return repository.getContent().toFile( artifact );
407 * Simple method to test if the file exists on the local disk.
409 * @param file the file to test. (may be null)
410 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
412 private boolean fileExists( StorageAsset file )
424 return !file.isContainer();
428 * Perform the transfer of the file.
430 * @param connector the connector configuration to use.
431 * @param remoteRepository the remote repository get the resource from.
432 * @param remotePath the path in the remote repository to the resource to get.
433 * @param repository the managed repository that will hold the file
434 * @param resource the path relative to the repository storage where the file should be downloaded to
435 * @param requestProperties the request properties to utilize for policy handling.
436 * @param executeConsumers whether to execute the consumers after proxying
437 * @return the local file that was downloaded, or null if not downloaded.
438 * @throws NotFoundException if the file was not found on the remote repository.
439 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, but
440 * the remote resource is not newer than the local File.
441 * @throws ProxyException if transfer was unsuccessful.
443 protected StorageAsset transferFile( ProxyConnector connector, RemoteRepository remoteRepository, String remotePath,
444 ManagedRepository repository, StorageAsset resource, Properties requestProperties,
445 boolean executeConsumers )
446 throws ProxyException, NotModifiedException
451 url = remoteRepository.getLocation().toURL().toString();
453 catch ( MalformedURLException e )
455 throw new ProxyException( e.getMessage(), e );
457 if ( !url.endsWith( "/" ) )
461 url = url + remotePath;
462 requestProperties.setProperty( "url", url );
464 // Is a whitelist defined?
465 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
467 // Path must belong to whitelist.
468 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
470 log.debug( "Path [{}] is not part of defined whitelist (skipping transfer from repository [{}]).",
471 remotePath, remoteRepository.getId() );
476 // Is target path part of blacklist?
477 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
479 log.debug( "Path [{}] is part of blacklist (skipping transfer from repository [{}]).", remotePath,
480 remoteRepository.getId() );
484 // Handle pre-download policy
487 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, resource );
489 catch ( PolicyViolationException e )
491 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
492 if ( resource.exists() )
494 log.debug( "{} : using already present local file.", emsg );
502 Path workingDirectory = createWorkingDirectory( repository );
503 FilesystemStorage tmpStorage = null;
506 tmpStorage = new FilesystemStorage( workingDirectory, fileLockManager );
508 catch ( IOException e )
510 throw new ProxyException( "Could not create tmp storage" );
512 StorageAsset tmpResource = tmpStorage.getAsset( resource.getName( ) );
513 StorageAsset[] tmpChecksumFiles = new StorageAsset[checksumAlgorithms.size()];
514 for(int i=0; i<checksumAlgorithms.size(); i++) {
515 ChecksumAlgorithm alg = checksumAlgorithms.get( i );
516 tmpChecksumFiles[i] = tmpStorage.getAsset( resource.getName() + "." + alg.getDefaultExtension() );
522 transferResources( connector, remoteRepository, tmpResource,tmpChecksumFiles , url, remotePath,
523 resource, workingDirectory, repository );
525 // Handle post-download policies.
528 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, tmpResource );
530 catch ( PolicyViolationException e )
532 log.warn( "Transfer invalidated from {} : {}", url, e.getMessage() );
533 executeConsumers = false;
534 if ( !fileExists( tmpResource ) )
540 if ( resource != null )
542 synchronized ( resource.getPath().intern() )
544 StorageAsset directory = resource.getParent();
545 for (int i=0; i<tmpChecksumFiles.length; i++) {
546 moveFileIfExists( tmpChecksumFiles[i], directory );
548 moveFileIfExists( tmpResource, directory );
554 org.apache.archiva.common.utils.FileUtils.deleteQuietly( workingDirectory );
557 if ( executeConsumers )
559 // Just-in-time update of the index and database by executing the consumers for this artifact
560 //consumers.executeConsumers( connector.getSourceRepository().getRepository(), resource );
561 queueRepositoryTask( connector.getSourceRepository().getId(), resource );
567 protected abstract void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
568 StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource, Path workingDirectory,
569 ManagedRepository repository ) throws ProxyException;
571 private void queueRepositoryTask(String repositoryId, StorageAsset localFile )
573 RepositoryTask task = new RepositoryTask();
574 task.setRepositoryId( repositoryId );
575 task.setResourceFile( localFile );
576 task.setUpdateRelatedArtifacts( true );
577 task.setScanAll( true );
581 scheduler.queueTask( task );
583 catch ( TaskQueueException e )
585 log.error( "Unable to queue repository task to execute consumers on resource file ['{}"
586 + "'].", localFile.getName() );
591 * Moves the file into repository location if it exists
593 * @param fileToMove this could be either the main artifact, sha1 or md5 checksum file.
594 * @param directory directory to write files to
596 private void moveFileIfExists( StorageAsset fileToMove, StorageAsset directory )
597 throws ProxyException
599 if ( fileToMove != null && fileToMove.exists() )
601 StorageAsset newLocation = directory.getStorage().getAsset( directory.getPath()+ "/" + fileToMove.getName());
602 moveTempToTarget( fileToMove, newLocation );
607 * Apply the policies.
609 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
610 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy
612 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)}
614 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(PolicyOption, Properties, StorageAsset)})
615 * @throws PolicyViolationException
617 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<Policy, PolicyOption> settings,
618 Properties request, StorageAsset localFile )
619 throws PolicyViolationException
621 for ( Map.Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
623 // olamy with spring rolehint is now downloadPolicy#hint
624 // so substring after last # to get the hint as with plexus
625 String key = entry.getValue( ).getId( );
626 DownloadPolicy policy = entry.getValue();
627 PolicyOption option = settings.containsKey(policy ) ? settings.get(policy) : policy.getDefaultOption();
629 log.debug( "Applying [{}] policy with [{}]", key, option );
632 policy.applyPolicy( option, request, localFile );
634 catch ( PolicyConfigurationException e )
636 log.error( e.getMessage(), e );
641 private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<Policy, PolicyOption> settings,
642 Properties request, ArtifactReference artifact, RemoteRepositoryContent content,
643 StorageAsset localFile, Exception exception, Map<String, Exception> previousExceptions )
644 throws ProxyDownloadException
646 boolean process = true;
647 for ( Map.Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() )
650 // olamy with spring rolehint is now downloadPolicy#hint
651 // so substring after last # to get the hint as with plexus
652 String key = entry.getValue( ).getId( );
653 DownloadErrorPolicy policy = entry.getValue();
654 PolicyOption option = settings.containsKey( policy ) ? settings.get(policy) : policy.getDefaultOption();
656 log.debug( "Applying [{}] policy with [{}]", key, option );
659 // all policies must approve the exception, any can cancel
660 process = policy.applyPolicy( option, request, localFile, exception, previousExceptions );
666 catch ( PolicyConfigurationException e )
668 log.error( e.getMessage(), e );
674 // if the exception was queued, don't throw it
675 if ( !previousExceptions.containsKey( content.getId() ) )
677 throw new ProxyDownloadException(
678 "An error occurred in downloading from the remote repository, and the policy is to fail immediately",
679 content.getId(), exception );
684 // if the exception was queued, but cancelled, remove it
685 previousExceptions.remove( content.getId() );
689 "Transfer error from repository {} for artifact {} , continuing to next repository. Error message: {}",
690 content.getRepository().getId(), Keys.toKey( artifact ), exception.getMessage() );
691 log.debug( "Full stack trace", exception );
695 * Creates a working directory
698 * @return file location of working directory
700 private Path createWorkingDirectory( ManagedRepository repository )
704 return Files.createTempDirectory( "temp" );
706 catch ( IOException e )
708 throw new RuntimeException( e.getMessage(), e );
714 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles its
717 * @param temp The completed download file
718 * @param target The final location of the downloaded file
719 * @throws ProxyException when the temp file cannot replace the target file
721 private void moveTempToTarget( StorageAsset temp, StorageAsset target )
722 throws ProxyException
727 StorageUtil.moveAsset( temp, target, true , StandardCopyOption.REPLACE_EXISTING);
729 catch ( IOException e )
731 log.error( "Move failed from {} to {}, trying copy.", temp, target );
734 StorageUtil.copyAsset( temp, target, true );
736 temp.getStorage( ).removeAsset( temp );
739 catch ( IOException ex )
741 log.error("Copy failed from {} to {}: ({}) {}", temp, target, e.getClass(), e.getMessage());
742 throw new ProxyException("Could not move temp file "+temp.getPath()+" to target "+target.getPath()+": ("+e.getClass()+") "+e.getMessage(), e);
748 * Tests whitelist and blacklist patterns against path.
750 * @param path the path to test.
751 * @param patterns the list of patterns to check.
752 * @return true if the path matches at least 1 pattern in the provided patterns list.
754 private boolean matchesPattern( String path, List<String> patterns )
756 if ( CollectionUtils.isEmpty( patterns ) )
761 if ( !path.startsWith( "/" ) )
766 for ( String pattern : patterns )
768 if ( !pattern.startsWith( "/" ) )
770 pattern = "/" + pattern;
773 if ( SelectorUtils.matchPath( pattern, path, false ) )
783 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
787 public List<ProxyConnector> getProxyConnectors( ManagedRepository repository )
790 if ( !this.proxyConnectorMap.containsKey( repository.getId() ) )
792 return Collections.emptyList();
794 List<ProxyConnector> ret = new ArrayList<>( this.proxyConnectorMap.get( repository.getId() ) );
796 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
802 protected String addParameters(String path, RemoteRepository remoteRepository )
804 if ( remoteRepository.getExtraParameters().isEmpty() )
809 boolean question = false;
811 StringBuilder res = new StringBuilder( path == null ? "" : path );
813 for ( Map.Entry<String, String> entry : remoteRepository.getExtraParameters().entrySet() )
817 res.append( '?' ).append( entry.getKey() ).append( '=' ).append( entry.getValue() );
821 return res.toString();
824 public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration )
826 this.archivaConfiguration = archivaConfiguration;
829 public MetadataTools getMetadataTools()
831 return metadataTools;
834 public void setMetadataTools(MetadataTools metadataTools )
836 this.metadataTools = metadataTools;
839 public UrlFailureCache getUrlFailureCache()
841 return urlFailureCache;
844 public void setUrlFailureCache(UrlFailureCache urlFailureCache )
846 this.urlFailureCache = urlFailureCache;
849 public Map<String, PreDownloadPolicy> getPreDownloadPolicies()
851 return preDownloadPolicies;
854 public void setPreDownloadPolicies(Map<String, PreDownloadPolicy> preDownloadPolicies )
856 this.preDownloadPolicies = preDownloadPolicies;
859 public Map<String, PostDownloadPolicy> getPostDownloadPolicies()
861 return postDownloadPolicies;
864 public void setPostDownloadPolicies(Map<String, PostDownloadPolicy> postDownloadPolicies )
866 this.postDownloadPolicies = postDownloadPolicies;
869 public Map<String, DownloadErrorPolicy> getDownloadErrorPolicies()
871 return downloadErrorPolicies;
874 public void setDownloadErrorPolicies(Map<String, DownloadErrorPolicy> downloadErrorPolicies )
876 this.downloadErrorPolicies = downloadErrorPolicies;
880 public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
881 this.networkProxyMap.clear();
882 this.networkProxyMap.putAll( networkProxies );
886 public NetworkProxy getNetworkProxy(String id) {
887 return this.networkProxyMap.get(id);
891 public Map<String, NetworkProxy> getNetworkProxies() {
892 return this.networkProxyMap;
896 public abstract List<RepositoryType> supports();
899 public void setPolicies( List<Policy> policyList )
901 preDownloadPolicies.clear();
902 postDownloadPolicies.clear();
903 downloadErrorPolicies.clear();
904 for (Policy policy : policyList) {
909 void addPolicy(PreDownloadPolicy policy) {
910 preDownloadPolicies.put( policy.getId( ), policy );
913 void addPolicy(PostDownloadPolicy policy) {
914 postDownloadPolicies.put( policy.getId( ), policy );
916 void addPolicy(DownloadErrorPolicy policy) {
917 downloadErrorPolicies.put( policy.getId( ), policy );
921 public void addPolicy( Policy policy )
923 if (policy instanceof PreDownloadPolicy) {
924 addPolicy( (PreDownloadPolicy)policy );
925 } else if (policy instanceof PostDownloadPolicy) {
926 addPolicy( (PostDownloadPolicy) policy );
927 } else if (policy instanceof DownloadErrorPolicy) {
928 addPolicy( (DownloadErrorPolicy) policy );
930 log.warn( "Policy not known: {}, {}", policy.getId( ), policy.getClass( ).getName( ) );
935 public void removePolicy( Policy policy )
937 final String id = policy.getId();
938 if (preDownloadPolicies.containsKey( id )) {
939 preDownloadPolicies.remove( id );
940 } else if (postDownloadPolicies.containsKey( id )) {
941 postDownloadPolicies.remove( id );
942 } else if (downloadErrorPolicies.containsKey( id )) {
943 downloadErrorPolicies.remove( id );
948 public void addProxyConnector( ProxyConnector connector )
950 final String sourceId = connector.getSourceRepository( ).getId( );
951 List<ProxyConnector> connectors;
952 if (proxyConnectorMap.containsKey( sourceId )) {
953 connectors = proxyConnectorMap.get( sourceId );
955 connectors = new ArrayList<>( );
956 proxyConnectorMap.put( sourceId, connectors );
958 connectors.add( connector );
962 public void setProxyConnectors( List<ProxyConnector> proxyConnectors )
964 proxyConnectorMap.clear();
965 for ( ProxyConnector connector : proxyConnectors )
967 addProxyConnector( connector );