1 package org.apache.maven.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
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
29 import java.util.Properties;
30 import java.util.Map.Entry;
32 import org.apache.commons.collections.CollectionUtils;
33 import org.apache.commons.io.FileUtils;
34 import org.apache.commons.lang.StringUtils;
35 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
36 import org.apache.maven.archiva.configuration.ConfigurationNames;
37 import org.apache.maven.archiva.configuration.NetworkProxyConfiguration;
38 import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
39 import org.apache.maven.archiva.model.ArtifactReference;
40 import org.apache.maven.archiva.model.Keys;
41 import org.apache.maven.archiva.model.ProjectReference;
42 import org.apache.maven.archiva.model.RepositoryURL;
43 import org.apache.maven.archiva.model.VersionedReference;
44 import org.apache.maven.archiva.policies.DownloadPolicy;
45 import org.apache.maven.archiva.policies.PolicyConfigurationException;
46 import org.apache.maven.archiva.policies.PolicyViolationException;
47 import org.apache.maven.archiva.policies.PostDownloadPolicy;
48 import org.apache.maven.archiva.policies.PreDownloadPolicy;
49 import org.apache.maven.archiva.policies.urlcache.UrlFailureCache;
50 import org.apache.maven.archiva.repository.ContentNotFoundException;
51 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
52 import org.apache.maven.archiva.repository.RemoteRepositoryContent;
53 import org.apache.maven.archiva.repository.RepositoryContentFactory;
54 import org.apache.maven.archiva.repository.RepositoryException;
55 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
56 import org.apache.maven.archiva.repository.layout.LayoutException;
57 import org.apache.maven.archiva.repository.metadata.MetadataTools;
58 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
59 import org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers;
60 import org.apache.maven.wagon.ConnectionException;
61 import org.apache.maven.wagon.ResourceDoesNotExistException;
62 import org.apache.maven.wagon.Wagon;
63 import org.apache.maven.wagon.WagonException;
64 import org.apache.maven.wagon.authentication.AuthenticationException;
65 import org.apache.maven.wagon.authentication.AuthenticationInfo;
66 import org.apache.maven.wagon.proxy.ProxyInfo;
67 import org.apache.maven.wagon.repository.Repository;
68 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
69 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
70 import org.codehaus.plexus.registry.Registry;
71 import org.codehaus.plexus.registry.RegistryListener;
72 import org.codehaus.plexus.util.SelectorUtils;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
77 * DefaultRepositoryProxyConnectors
79 * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
81 * @plexus.component role-hint="default"
83 public class DefaultRepositoryProxyConnectors
84 implements RepositoryProxyConnectors, RegistryListener, Initializable
86 private Logger log = LoggerFactory.getLogger( DefaultRepositoryProxyConnectors.class );
91 private ArchivaConfiguration archivaConfiguration;
94 * @plexus.requirement role="org.apache.maven.wagon.Wagon"
96 private Map<String, Wagon> wagons;
101 private RepositoryContentFactory repositoryFactory;
104 * @plexus.requirement
106 private MetadataTools metadataTools;
109 * @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
111 private Map<String, PreDownloadPolicy> preDownloadPolicies;
114 * @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
116 private Map<String, PostDownloadPolicy> postDownloadPolicies;
119 * @plexus.requirement
121 private UrlFailureCache urlFailureCache;
123 private Map<String, List<ProxyConnector>> proxyConnectorMap = new HashMap<String, List<ProxyConnector>>();
125 private Map<String, ProxyInfo> networkProxyMap = new HashMap<String, ProxyInfo>();
128 * @plexus.requirement
130 private RepositoryContentConsumers consumers;
133 * Fetch an artifact from a remote repository.
135 * @param repository the managed repository to utilize for the request.
136 * @param artifact the artifact reference to fetch.
137 * @return the local file in the managed repository that was fetched, or null if the artifact was not (or
138 * could not be) fetched.
139 * @throws ProxyException if there was a problem fetching the artifact.
141 public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact )
143 File localFile = toLocalFile( repository, artifact );
145 Properties requestProperties = new Properties();
146 requestProperties.setProperty( "filetype", "artifact" );
147 requestProperties.setProperty( "version", artifact.getVersion() );
149 List<ProxyConnector> connectors = getProxyConnectors( repository );
150 for ( ProxyConnector connector : connectors )
152 RemoteRepositoryContent targetRepository = connector.getTargetRepository();
153 String targetPath = targetRepository.toPath( artifact );
157 File downloadedFile = transferFile( connector, targetRepository, targetPath, localFile,
160 if ( fileExists( downloadedFile ) )
162 log.debug( "Successfully transferred: " + downloadedFile.getAbsolutePath() );
163 return downloadedFile;
166 catch ( NotFoundException e )
168 log.debug( "Artifact " + Keys.toKey( artifact ) + " not found on repository \""
169 + targetRepository.getRepository().getId() + "\"." );
171 catch ( NotModifiedException e )
173 log.debug( "Artifact " + Keys.toKey( artifact ) + " not updated on repository \""
174 + targetRepository.getRepository().getId() + "\"." );
176 catch ( ProxyException e )
178 log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() +
179 "\" for artifact " + Keys.toKey( artifact ) + ", continuing to next repository. Error message: " +
181 log.debug( "Full stack trace", e );
184 log.debug( "Exhausted all target repositories, artifact " + Keys.toKey( artifact ) + " not found." );
190 * Fetch, from the proxies, a metadata.xml file for the groupId:artifactId:version metadata contents.
192 * @return the (local) metadata file that was fetched/merged/updated, or null if no metadata file exists.
194 public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata )
196 File localFile = toLocalFile( repository, metadata );
198 Properties requestProperties = new Properties();
199 requestProperties.setProperty( "filetype", "metadata" );
200 boolean metadataNeedsUpdating = false;
201 long originalTimestamp = getLastModified( localFile );
203 List<ProxyConnector> connectors = getProxyConnectors( repository );
204 for ( ProxyConnector connector : connectors )
206 RemoteRepositoryContent targetRepository = connector.getTargetRepository();
207 String targetPath = metadataTools.toPath( metadata );
209 File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath );
210 long originalMetadataTimestamp = getLastModified( localRepoFile );
214 transferFile( connector, targetRepository, targetPath, localRepoFile, requestProperties );
216 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
218 metadataNeedsUpdating = true;
221 catch ( NotFoundException e )
223 log.debug( "Versioned Metadata " + Keys.toKey( metadata )
224 + " not found on remote repository \""
225 + targetRepository.getRepository().getId() + "\"." );
227 catch ( NotModifiedException e )
229 log.debug( "Versioned Metadata " + Keys.toKey( metadata )
230 + " not updated on remote repository \""
231 + targetRepository.getRepository().getId() + "\"." );
233 catch ( ProxyException e )
235 log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() +
236 "\" for versioned Metadata " + Keys.toKey( metadata ) +
237 ", continuing to next repository. Error message: " + e.getMessage() );
238 log.debug( "Full stack trace", e );
242 if ( hasBeenUpdated( localFile, originalTimestamp ) )
244 metadataNeedsUpdating = true;
247 if ( metadataNeedsUpdating )
251 metadataTools.updateMetadata( repository, metadata );
253 catch ( LayoutException e )
255 log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage() );
256 // TODO: add into repository report?
258 catch ( RepositoryMetadataException e )
261 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
262 // TODO: add into repository report?
264 catch ( IOException e )
267 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
268 // TODO: add into repository report?
270 catch ( ContentNotFoundException e )
273 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
274 // TODO: add into repository report?
278 if ( fileExists( localFile ) )
286 private long getLastModified( File file )
288 if ( !file.exists() || !file.isFile() )
293 return file.lastModified();
296 private boolean hasBeenUpdated( File file, long originalLastModified )
298 if ( !file.exists() || !file.isFile() )
303 long currentLastModified = getLastModified( file );
304 return ( currentLastModified > originalLastModified );
308 * Fetch from the proxies a metadata.xml file for the groupId:artifactId metadata contents.
310 * @return the (local) metadata file that was fetched/merged/updated, or null if no metadata file exists.
311 * @throws ProxyException if there was a problem fetching the metadata file.
313 public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata )
315 File localFile = toLocalFile( repository, metadata );
317 Properties requestProperties = new Properties();
318 requestProperties.setProperty( "filetype", "metadata" );
319 boolean metadataNeedsUpdating = false;
320 long originalTimestamp = getLastModified( localFile );
322 List<ProxyConnector> connectors = getProxyConnectors( repository );
323 for ( ProxyConnector connector : connectors )
325 RemoteRepositoryContent targetRepository = connector.getTargetRepository();
326 String targetPath = metadataTools.toPath( metadata );
328 File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath );
329 long originalMetadataTimestamp = getLastModified( localRepoFile );
332 transferFile( connector, targetRepository, targetPath, localRepoFile, requestProperties );
334 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
336 metadataNeedsUpdating = true;
339 catch ( NotFoundException e )
341 log.debug( "Project Metadata " + Keys.toKey( metadata ) + " not found on remote repository \""
342 + targetRepository.getRepository().getId() + "\"." );
344 catch ( NotModifiedException e )
346 log.debug( "Project Metadata " + Keys.toKey( metadata )
347 + " not updated on remote repository \""
348 + targetRepository.getRepository().getId() + "\"." );
350 catch ( ProxyException e )
352 log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() +
353 "\" for project metadata " + Keys.toKey( metadata ) +
354 ", continuing to next repository. Error message: " + e.getMessage() );
355 log.debug( "Full stack trace", e );
360 if ( hasBeenUpdated( localFile, originalTimestamp ) )
362 metadataNeedsUpdating = true;
365 if ( metadataNeedsUpdating )
369 metadataTools.updateMetadata( repository, metadata );
371 catch ( LayoutException e )
373 log.warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage() );
374 // TODO: add into repository report?
376 catch ( RepositoryMetadataException e )
379 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
380 // TODO: add into repository report?
382 catch ( IOException e )
385 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
386 // TODO: add into repository report?
388 catch ( ContentNotFoundException e )
391 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
392 // TODO: add into repository report?
396 if ( fileExists( localFile ) )
404 private File toLocalRepoFile( ManagedRepositoryContent repository, RemoteRepositoryContent targetRepository,
407 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
408 return new File( repository.getRepoRoot(), repoPath );
412 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
414 public boolean hasProxies( ManagedRepositoryContent repository )
416 synchronized ( this.proxyConnectorMap )
418 return this.proxyConnectorMap.containsKey( repository.getId() );
422 private File toLocalFile( ManagedRepositoryContent repository, ArtifactReference artifact )
424 return repository.toFile( artifact );
427 private File toLocalFile( ManagedRepositoryContent repository, ProjectReference metadata )
429 String sourcePath = metadataTools.toPath( metadata );
430 return new File( repository.getRepoRoot(), sourcePath );
433 private File toLocalFile( ManagedRepositoryContent repository, VersionedReference metadata )
435 String sourcePath = metadataTools.toPath( metadata );
436 return new File( repository.getRepoRoot(), sourcePath );
440 * Simple method to test if the file exists on the local disk.
442 * @param file the file to test. (may be null)
443 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
445 private boolean fileExists( File file )
452 if ( !file.exists() )
457 if ( !file.isFile() )
466 * Perform the transfer of the file.
468 * @param connector the connector configuration to use.
469 * @param remoteRepository the remote repository get the resource from.
470 * @param remotePath the path in the remote repository to the resource to get.
471 * @param localFile the local file to place the downloaded resource into
472 * @param requestProperties the request properties to utilize for policy handling.
473 * @return the local file that was downloaded, or null if not downloaded.
474 * @throws NotFoundException if the file was not found on the remote repository.
475 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository,
476 * but the remote resource is not newer than the local File.
477 * @throws ProxyException if transfer was unsuccessful.
479 private File transferFile( ProxyConnector connector, RemoteRepositoryContent remoteRepository, String remotePath,
480 File localFile, Properties requestProperties )
481 throws ProxyException, NotModifiedException
483 String url = remoteRepository.getURL().getUrl();
484 if ( !url.endsWith( "/" ) )
488 url = url + remotePath;
489 requestProperties.setProperty( "url", url );
491 // Is a whitelist defined?
492 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
494 // Path must belong to whitelist.
495 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
497 log.debug( "Path [" + remotePath +
498 "] is not part of defined whitelist (skipping transfer from repository [" +
499 remoteRepository.getRepository().getName() + "])." );
504 // Is target path part of blacklist?
505 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
507 log.debug( "Path [" + remotePath + "] is part of blacklist (skipping transfer from repository [" +
508 remoteRepository.getRepository().getName() + "])." );
512 // Handle pre-download policy
515 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, localFile );
517 catch ( PolicyViolationException e )
519 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
520 if ( fileExists( localFile ) )
522 log.info( emsg + ": using already present local file." );
533 RepositoryURL repoUrl = remoteRepository.getURL();
534 String protocol = repoUrl.getProtocol();
535 wagon = (Wagon) wagons.get( protocol );
538 throw new ProxyException( "Unsupported target repository protocol: " + protocol );
541 boolean connected = connectToRepository( connector, wagon, remoteRepository );
544 localFile = transferSimpleFile( wagon, remoteRepository, remotePath, localFile );
546 transferChecksum( wagon, remoteRepository, remotePath, localFile, ".sha1" );
547 transferChecksum( wagon, remoteRepository, remotePath, localFile, ".md5" );
550 catch ( NotFoundException e )
552 urlFailureCache.cacheFailure( url );
555 catch ( NotModifiedException e )
557 // Do not cache url here.
560 catch ( ProxyException e )
562 urlFailureCache.cacheFailure( url );
573 catch ( ConnectionException e )
575 log.warn( "Unable to disconnect wagon.", e );
580 // Handle post-download policies.
583 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, localFile );
585 catch ( PolicyViolationException e )
587 log.info( "Transfer invalidated from " + url + " : " + e.getMessage() );
588 if ( fileExists( localFile ) )
596 // Just-in-time update of the index and database by executing the consumers for this artifact
597 consumers.executeConsumers( connector.getSourceRepository().getRepository(), localFile );
599 // Everything passes.
605 * Quietly transfer the checksum file from the remote repository to the local file.
608 * @param wagon the wagon instance (should already be connected) to use.
609 * @param remoteRepository the remote repository to transfer from.
610 * @param remotePath the remote path to the resource to get.
611 * @param localFile the local file that should contain the downloaded contents
612 * @param type the type of checksum to transfer (example: ".md5" or ".sha1")
613 * @throws ProxyException if copying the downloaded file into place did not succeed.
615 private void transferChecksum( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
616 File localFile, String type )
617 throws ProxyException
619 String url = remoteRepository.getURL().getUrl() + remotePath;
621 // Transfer checksum does not use the policy.
622 if ( urlFailureCache.hasFailedBefore( url + type ) )
629 File hashFile = new File( localFile.getAbsolutePath() + type );
630 transferSimpleFile( wagon, remoteRepository, remotePath + type, hashFile );
631 log.debug( "Checksum" + type + " Downloaded: " + hashFile );
633 catch ( NotFoundException e )
635 log.debug( "Transfer failed, checksum not found: " + url );
636 // Consume it, do not pass this on.
638 catch ( NotModifiedException e )
640 log.debug( "Transfer skipped, checksum not modified: " + url );
641 // Consume it, do not pass this on.
643 catch ( ProxyException e )
645 urlFailureCache.cacheFailure( url + type );
646 log.warn( "Transfer failed on checksum: " + url + " : " + e.getMessage(), e );
647 // Critical issue, pass it on.
653 * Perform the transfer of the remote file to the local file specified.
655 * @param wagon the wagon instance to use.
656 * @param remoteRepository the remote repository to use
657 * @param remotePath the remote path to attempt to get
658 * @param localFile the local file to save to
659 * @return The local file that was transfered.
660 * @throws ProxyException if there was a problem moving the downloaded file into place.
661 * @throws WagonException if there was a problem tranfering the file.
663 private File transferSimpleFile( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
665 throws ProxyException
667 assert ( remotePath != null );
669 // Transfer the file.
674 temp = new File( localFile.getAbsolutePath() + ".tmp" );
676 boolean success = false;
678 if ( !localFile.exists() )
680 log.debug( "Retrieving " + remotePath + " from " + remoteRepository.getRepository().getName() );
681 wagon.get( remotePath, temp );
686 moveTempToTarget( temp, localFile );
689 // You wouldn't get here on failure, a WagonException would have been thrown.
690 log.debug( "Downloaded successfully." );
694 log.debug( "Retrieving " + remotePath + " from " + remoteRepository.getRepository().getName()
696 success = wagon.getIfNewer( remotePath, temp, localFile.lastModified() );
699 throw new NotModifiedException( "Not downloaded, as local file is newer than remote side: "
700 + localFile.getAbsolutePath() );
705 log.debug( "Downloaded successfully." );
706 moveTempToTarget( temp, localFile );
712 catch ( ResourceDoesNotExistException e )
714 throw new NotFoundException( "Resource [" + remoteRepository.getURL() + "/" + remotePath
715 + "] does not exist: " + e.getMessage(), e );
717 catch ( WagonException e )
719 throw new ProxyException( "Download failure on resource [" + remoteRepository.getURL() + "/" + remotePath + "]:"
720 + e.getMessage(), e );
732 * Apply the policies.
734 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
735 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy setting)
736 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(String,Properties,File)})
737 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(String,Properties,File)})
739 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<String, String> settings,
740 Properties request, File localFile )
741 throws PolicyViolationException
743 for ( Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
745 String key = (String) entry.getKey();
746 DownloadPolicy policy = entry.getValue();
747 String defaultSetting = policy.getDefaultOption();
748 String setting = StringUtils.defaultString( (String) settings.get( key ), defaultSetting );
750 log.debug( "Applying [" + key + "] policy with [" + setting + "]" );
753 policy.applyPolicy( setting, request, localFile );
755 catch ( PolicyConfigurationException e )
757 log.error( e.getMessage(), e );
763 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles
764 * its downloaded files.
766 * @param temp The completed download file
767 * @param target The final location of the downloaded file
768 * @throws ProxyException when the temp file cannot replace the target file
770 private void moveTempToTarget( File temp, File target )
771 throws ProxyException
773 if ( target.exists() && !target.delete() )
775 throw new ProxyException( "Unable to overwrite existing target file: " + target.getAbsolutePath() );
778 if ( !temp.renameTo( target ) )
780 log.warn( "Unable to rename tmp file to its final name... resorting to copy command." );
784 FileUtils.copyFile( temp, target );
786 catch ( IOException e )
788 throw new ProxyException( "Cannot copy tmp file to its final location", e );
798 * Using wagon, connect to the remote repository.
800 * @param connector the connector configuration to utilize (for obtaining network proxy configuration from)
801 * @param wagon the wagon instance to establish the connection on.
802 * @param remoteRepository the remote repository to connect to.
803 * @return true if the connection was successful. false if not connected.
805 private boolean connectToRepository( ProxyConnector connector, Wagon wagon, RemoteRepositoryContent remoteRepository )
807 boolean connected = false;
809 ProxyInfo networkProxy = null;
810 synchronized ( this.networkProxyMap )
812 networkProxy = (ProxyInfo) this.networkProxyMap.get( connector.getProxyId() );
817 AuthenticationInfo authInfo = null;
818 String username = remoteRepository.getRepository().getUsername();
819 String password = remoteRepository.getRepository().getPassword();
821 if ( StringUtils.isNotBlank( username ) && StringUtils.isNotBlank( password ) )
823 log.debug( "Using username " + username + " to connect to remote repository "
824 + remoteRepository.getURL() );
825 authInfo = new AuthenticationInfo();
826 authInfo.setUserName( username );
827 authInfo.setPassword( password );
831 log.debug( "No authentication for remote repository needed" );
834 //Convert seconds to milliseconds
835 int timeoutInMilliseconds = remoteRepository.getRepository().getTimeout() * 1000;
838 wagon.setTimeout(timeoutInMilliseconds);
840 Repository wagonRepository = new Repository( remoteRepository.getId(), remoteRepository.getURL().toString() );
841 if ( networkProxy != null )
843 wagon.connect( wagonRepository, authInfo, networkProxy );
847 wagon.connect( wagonRepository, authInfo );
851 catch ( ConnectionException e )
854 "Could not connect to " + remoteRepository.getRepository().getName() + ": "
858 catch ( AuthenticationException e )
861 "Could not connect to " + remoteRepository.getRepository().getName() + ": "
870 * Tests whitelist and blacklist patterns against path.
872 * @param path the path to test.
873 * @param patterns the list of patterns to check.
874 * @return true if the path matches at least 1 pattern in the provided patterns list.
876 private boolean matchesPattern( String path, List<String> patterns )
878 if ( CollectionUtils.isEmpty( patterns ) )
883 for ( String pattern : patterns )
885 if ( SelectorUtils.matchPath( pattern, path, false ) )
895 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
897 public List<ProxyConnector> getProxyConnectors( ManagedRepositoryContent repository )
899 synchronized ( this.proxyConnectorMap )
901 List<ProxyConnector> ret = (List<ProxyConnector>) this.proxyConnectorMap.get( repository.getId() );
904 return Collections.EMPTY_LIST;
907 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
912 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
914 if ( ConfigurationNames.isNetworkProxy( propertyName )
915 || ConfigurationNames.isManagedRepositories( propertyName )
916 || ConfigurationNames.isRemoteRepositories( propertyName )
917 || ConfigurationNames.isProxyConnector( propertyName ) )
919 initConnectorsAndNetworkProxies();
923 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
928 private void logProcess( String managedRepoId, String resource, String event )
933 private void logRejection( String managedRepoId, String remoteRepoId, String resource, String reason )
938 private void initConnectorsAndNetworkProxies()
940 synchronized ( this.proxyConnectorMap )
942 ProxyConnectorOrderComparator proxyOrderSorter = new ProxyConnectorOrderComparator();
943 this.proxyConnectorMap.clear();
945 List<ProxyConnectorConfiguration> proxyConfigs = archivaConfiguration.getConfiguration()
946 .getProxyConnectors();
947 for ( ProxyConnectorConfiguration proxyConfig : proxyConfigs )
949 String key = proxyConfig.getSourceRepoId();
953 // Create connector object.
954 ProxyConnector connector = new ProxyConnector();
956 connector.setSourceRepository( repositoryFactory.getManagedRepositoryContent( proxyConfig
957 .getSourceRepoId() ) );
958 connector.setTargetRepository( repositoryFactory.getRemoteRepositoryContent( proxyConfig
959 .getTargetRepoId() ) );
961 connector.setProxyId( proxyConfig.getProxyId() );
962 connector.setPolicies( proxyConfig.getPolicies() );
963 connector.setOrder( proxyConfig.getOrder() );
965 // Copy any blacklist patterns.
966 List<String> blacklist = new ArrayList<String>();
967 if ( CollectionUtils.isNotEmpty( proxyConfig.getBlackListPatterns() ) )
969 blacklist.addAll( proxyConfig.getBlackListPatterns() );
971 connector.setBlacklist( blacklist );
973 // Copy any whitelist patterns.
974 List<String> whitelist = new ArrayList<String>();
975 if ( CollectionUtils.isNotEmpty( proxyConfig.getWhiteListPatterns() ) )
977 whitelist.addAll( proxyConfig.getWhiteListPatterns() );
979 connector.setWhitelist( whitelist );
981 // Get other connectors
982 List<ProxyConnector> connectors = this.proxyConnectorMap.get( key );
983 if ( connectors == null )
985 // Create if we are the first.
986 connectors = new ArrayList<ProxyConnector>();
989 // Add the connector.
990 connectors.add( connector );
992 // Ensure the list is sorted.
993 Collections.sort( connectors, proxyOrderSorter );
995 // Set the key to the list of connectors.
996 this.proxyConnectorMap.put( key, connectors );
998 catch ( RepositoryNotFoundException e )
1000 log.warn( "Unable to use proxy connector: " + e.getMessage(), e );
1002 catch ( RepositoryException e )
1004 log.warn( "Unable to use proxy connector: " + e.getMessage(), e );
1010 synchronized ( this.networkProxyMap )
1012 this.networkProxyMap.clear();
1014 List<NetworkProxyConfiguration> networkProxies = archivaConfiguration.getConfiguration()
1015 .getNetworkProxies();
1016 for ( NetworkProxyConfiguration networkProxyConfig : networkProxies )
1018 String key = networkProxyConfig.getId();
1020 ProxyInfo proxy = new ProxyInfo();
1022 proxy.setType( networkProxyConfig.getProtocol() );
1023 proxy.setHost( networkProxyConfig.getHost() );
1024 proxy.setPort( networkProxyConfig.getPort() );
1025 proxy.setUserName( networkProxyConfig.getUsername() );
1026 proxy.setPassword( networkProxyConfig.getPassword() );
1028 this.networkProxyMap.put( key, proxy );
1033 public void initialize()
1034 throws InitializationException
1036 initConnectorsAndNetworkProxies();
1037 archivaConfiguration.addChangeListener( this );