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
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.commons.io.FileUtils;
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
26 import org.apache.maven.archiva.configuration.ConfigurationNames;
27 import org.apache.maven.archiva.configuration.NetworkProxyConfiguration;
28 import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration;
29 import org.apache.maven.archiva.model.ArtifactReference;
30 import org.apache.maven.archiva.model.Keys;
31 import org.apache.maven.archiva.model.ProjectReference;
32 import org.apache.maven.archiva.model.RepositoryURL;
33 import org.apache.maven.archiva.model.VersionedReference;
34 import org.apache.maven.archiva.policies.DownloadPolicy;
35 import org.apache.maven.archiva.policies.PolicyConfigurationException;
36 import org.apache.maven.archiva.policies.PolicyViolationException;
37 import org.apache.maven.archiva.policies.PostDownloadPolicy;
38 import org.apache.maven.archiva.policies.PreDownloadPolicy;
39 import org.apache.maven.archiva.policies.urlcache.UrlFailureCache;
40 import org.apache.maven.archiva.repository.ContentNotFoundException;
41 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
42 import org.apache.maven.archiva.repository.RemoteRepositoryContent;
43 import org.apache.maven.archiva.repository.RepositoryContentFactory;
44 import org.apache.maven.archiva.repository.RepositoryException;
45 import org.apache.maven.archiva.repository.RepositoryNotFoundException;
46 import org.apache.maven.archiva.repository.layout.LayoutException;
47 import org.apache.maven.archiva.repository.metadata.MetadataTools;
48 import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
49 import org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers;
50 import org.apache.maven.wagon.ConnectionException;
51 import org.apache.maven.wagon.ResourceDoesNotExistException;
52 import org.apache.maven.wagon.Wagon;
53 import org.apache.maven.wagon.WagonException;
54 import org.apache.maven.wagon.authentication.AuthenticationException;
55 import org.apache.maven.wagon.authentication.AuthenticationInfo;
56 import org.apache.maven.wagon.proxy.ProxyInfo;
57 import org.apache.maven.wagon.repository.Repository;
58 import org.codehaus.plexus.logging.AbstractLogEnabled;
59 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
60 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
61 import org.codehaus.plexus.registry.Registry;
62 import org.codehaus.plexus.registry.RegistryListener;
63 import org.codehaus.plexus.util.SelectorUtils;
66 import java.io.IOException;
67 import java.util.ArrayList;
68 import java.util.Collections;
69 import java.util.HashMap;
70 import java.util.List;
72 import java.util.Map.Entry;
73 import java.util.Properties;
76 * DefaultRepositoryProxyConnectors
78 * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
80 * @plexus.component role-hint="default"
82 public class DefaultRepositoryProxyConnectors
83 extends AbstractLogEnabled
84 implements RepositoryProxyConnectors, RegistryListener, Initializable
89 private ArchivaConfiguration archivaConfiguration;
92 * @plexus.requirement role="org.apache.maven.wagon.Wagon"
94 private Map<String, Wagon> wagons;
99 private RepositoryContentFactory repositoryFactory;
102 * @plexus.requirement
104 private MetadataTools metadataTools;
107 * @plexus.requirement role="org.apache.maven.archiva.policies.PreDownloadPolicy"
109 private Map<String, PreDownloadPolicy> preDownloadPolicies;
112 * @plexus.requirement role="org.apache.maven.archiva.policies.PostDownloadPolicy"
114 private Map<String, PostDownloadPolicy> postDownloadPolicies;
117 * @plexus.requirement role-hint="default"
119 private UrlFailureCache urlFailureCache;
121 private Map<String, List<ProxyConnector>> proxyConnectorMap = new HashMap<String, List<ProxyConnector>>();
123 private Map<String, ProxyInfo> networkProxyMap = new HashMap<String, ProxyInfo>();
126 * @plexus.requirement
128 private RepositoryContentConsumers consumers;
131 * Fetch an artifact from a remote repository.
133 * @param repository the managed repository to utilize for the request.
134 * @param artifact the artifact reference to fetch.
135 * @return the local file in the managed repository that was fetched, or null if the artifact was not (or
136 * could not be) fetched.
137 * @throws ProxyException if there was a problem fetching the artifact.
139 public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact )
141 File localFile = toLocalFile( repository, artifact );
143 Properties requestProperties = new Properties();
144 requestProperties.setProperty( "filetype", "artifact" );
145 requestProperties.setProperty( "version", artifact.getVersion() );
147 List<ProxyConnector> connectors = getProxyConnectors( repository );
148 for ( ProxyConnector connector : connectors )
150 RemoteRepositoryContent targetRepository = connector.getTargetRepository();
151 String targetPath = targetRepository.toPath( artifact );
155 File downloadedFile = transferFile( connector, targetRepository, targetPath, localFile,
158 if ( fileExists( downloadedFile ) )
160 getLogger().debug( "Successfully transferred: " + downloadedFile.getAbsolutePath() );
161 return downloadedFile;
164 catch ( NotFoundException e )
166 getLogger().debug( "Artifact " + Keys.toKey( artifact ) + " not found on repository \""
167 + targetRepository.getRepository().getId() + "\"." );
169 catch ( NotModifiedException e )
171 getLogger().debug( "Artifact " + Keys.toKey( artifact ) + " not updated on repository \""
172 + targetRepository.getRepository().getId() + "\"." );
174 catch ( ProxyException e )
176 getLogger().warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() +
177 "\" for artifact " + Keys.toKey( artifact ) + ", continuing to next repository. Error message: " +
179 getLogger().debug( "Full stack trace", e );
182 getLogger().debug( "Exhausted all target repositories, artifact " + Keys.toKey( artifact ) + " not found." );
188 * Fetch, from the proxies, a metadata.xml file for the groupId:artifactId:version metadata contents.
190 * @return the (local) metadata file that was fetched/merged/updated, or null if no metadata file exists.
192 public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata )
194 File localFile = toLocalFile( repository, metadata );
196 Properties requestProperties = new Properties();
197 requestProperties.setProperty( "filetype", "metadata" );
198 boolean metadataNeedsUpdating = false;
199 long originalTimestamp = getLastModified( localFile );
201 List<ProxyConnector> connectors = getProxyConnectors( repository );
202 for ( ProxyConnector connector : connectors )
204 RemoteRepositoryContent targetRepository = connector.getTargetRepository();
205 String targetPath = metadataTools.toPath( metadata );
207 File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath );
208 long originalMetadataTimestamp = getLastModified( localRepoFile );
212 transferFile( connector, targetRepository, targetPath, localRepoFile, requestProperties );
214 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
216 metadataNeedsUpdating = true;
219 catch ( NotFoundException e )
221 getLogger().debug( "Versioned Metadata " + Keys.toKey( metadata )
222 + " not found on remote repository \""
223 + targetRepository.getRepository().getId() + "\"." );
225 catch ( NotModifiedException e )
227 getLogger().debug( "Versioned Metadata " + Keys.toKey( metadata )
228 + " not updated on remote repository \""
229 + targetRepository.getRepository().getId() + "\"." );
231 catch ( ProxyException e )
233 getLogger().warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() +
234 "\" for versioned Metadata " + Keys.toKey( metadata ) +
235 ", continuing to next repository. Error message: " + e.getMessage() );
236 getLogger().debug( "Full stack trace", e );
240 if ( hasBeenUpdated( localFile, originalTimestamp ) )
242 metadataNeedsUpdating = true;
245 if ( metadataNeedsUpdating )
249 metadataTools.updateMetadata( repository, metadata );
251 catch ( LayoutException e )
253 getLogger().warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage() );
254 // TODO: add into repository report?
256 catch ( RepositoryMetadataException e )
259 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
260 // TODO: add into repository report?
262 catch ( IOException e )
265 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
266 // TODO: add into repository report?
268 catch ( ContentNotFoundException e )
271 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
272 // TODO: add into repository report?
276 if ( fileExists( localFile ) )
284 private long getLastModified( File file )
286 if ( !file.exists() || !file.isFile() )
291 return file.lastModified();
294 private boolean hasBeenUpdated( File file, long originalLastModified )
296 if ( !file.exists() || !file.isFile() )
301 long currentLastModified = getLastModified( file );
302 return ( currentLastModified > originalLastModified );
306 * Fetch from the proxies a metadata.xml file for the groupId:artifactId metadata contents.
308 * @return the (local) metadata file that was fetched/merged/updated, or null if no metadata file exists.
309 * @throws ProxyException if there was a problem fetching the metadata file.
311 public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata )
313 File localFile = toLocalFile( repository, metadata );
315 Properties requestProperties = new Properties();
316 requestProperties.setProperty( "filetype", "metadata" );
317 boolean metadataNeedsUpdating = false;
318 long originalTimestamp = getLastModified( localFile );
320 List<ProxyConnector> connectors = getProxyConnectors( repository );
321 for ( ProxyConnector connector : connectors )
323 RemoteRepositoryContent targetRepository = connector.getTargetRepository();
324 String targetPath = metadataTools.toPath( metadata );
326 File localRepoFile = toLocalRepoFile( repository, targetRepository, targetPath );
327 long originalMetadataTimestamp = getLastModified( localRepoFile );
330 transferFile( connector, targetRepository, targetPath, localRepoFile, requestProperties );
332 if ( hasBeenUpdated( localRepoFile, originalMetadataTimestamp ) )
334 metadataNeedsUpdating = true;
337 catch ( NotFoundException e )
339 getLogger().debug( "Project Metadata " + Keys.toKey( metadata ) + " not found on remote repository \""
340 + targetRepository.getRepository().getId() + "\"." );
342 catch ( NotModifiedException e )
344 getLogger().debug( "Project Metadata " + Keys.toKey( metadata )
345 + " not updated on remote repository \""
346 + targetRepository.getRepository().getId() + "\"." );
348 catch ( ProxyException e )
350 getLogger().warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() +
351 "\" for project metadata " + Keys.toKey( metadata ) +
352 ", continuing to next repository. Error message: " + e.getMessage() );
353 getLogger().debug( "Full stack trace", e );
358 if ( hasBeenUpdated( localFile, originalTimestamp ) )
360 metadataNeedsUpdating = true;
363 if ( metadataNeedsUpdating )
367 metadataTools.updateMetadata( repository, metadata );
369 catch ( LayoutException e )
371 getLogger().warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage() );
372 // TODO: add into repository report?
374 catch ( RepositoryMetadataException e )
377 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
378 // TODO: add into repository report?
380 catch ( IOException e )
383 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
384 // TODO: add into repository report?
386 catch ( ContentNotFoundException e )
389 .warn( "Unable to update metadata " + localFile.getAbsolutePath() + ": " + e.getMessage(), e );
390 // TODO: add into repository report?
394 if ( fileExists( localFile ) )
402 private File toLocalRepoFile( ManagedRepositoryContent repository, RemoteRepositoryContent targetRepository,
405 String repoPath = metadataTools.getRepositorySpecificName( targetRepository, targetPath );
406 return new File( repository.getRepoRoot(), repoPath );
410 * Test if the provided ManagedRepositoryContent has any proxies configured for it.
412 public boolean hasProxies( ManagedRepositoryContent repository )
414 synchronized ( this.proxyConnectorMap )
416 return this.proxyConnectorMap.containsKey( repository.getId() );
420 private File toLocalFile( ManagedRepositoryContent repository, ArtifactReference artifact )
422 return repository.toFile( artifact );
425 private File toLocalFile( ManagedRepositoryContent repository, ProjectReference metadata )
427 String sourcePath = metadataTools.toPath( metadata );
428 return new File( repository.getRepoRoot(), sourcePath );
431 private File toLocalFile( ManagedRepositoryContent repository, VersionedReference metadata )
433 String sourcePath = metadataTools.toPath( metadata );
434 return new File( repository.getRepoRoot(), sourcePath );
438 * Simple method to test if the file exists on the local disk.
440 * @param file the file to test. (may be null)
441 * @return true if file exists. false if the file param is null, doesn't exist, or is not of type File.
443 private boolean fileExists( File file )
450 if ( !file.exists() )
455 if ( !file.isFile() )
464 * Perform the transfer of the file.
466 * @param connector the connector configuration to use.
467 * @param remoteRepository the remote repository get the resource from.
468 * @param remotePath the path in the remote repository to the resource to get.
469 * @param localFile the local file to place the downloaded resource into
470 * @param requestProperties the request properties to utilize for policy handling.
471 * @return the local file that was downloaded, or null if not downloaded.
472 * @throws NotFoundException if the file was not found on the remote repository.
473 * @throws NotModifiedException if the localFile was present, and the resource was present on remote repository,
474 * but the remote resource is not newer than the local File.
475 * @throws ProxyException if transfer was unsuccessful.
477 private File transferFile( ProxyConnector connector, RemoteRepositoryContent remoteRepository, String remotePath,
478 File localFile, Properties requestProperties )
479 throws ProxyException, NotModifiedException
481 String url = remoteRepository.getURL().getUrl();
482 if ( !url.endsWith( "/" ) )
486 url = url + remotePath;
487 requestProperties.setProperty( "url", url );
489 // Is a whitelist defined?
490 if ( CollectionUtils.isNotEmpty( connector.getWhitelist() ) )
492 // Path must belong to whitelist.
493 if ( !matchesPattern( remotePath, connector.getWhitelist() ) )
495 getLogger().debug( "Path [" + remotePath +
496 "] is not part of defined whitelist (skipping transfer from repository [" +
497 remoteRepository.getRepository().getName() + "])." );
502 // Is target path part of blacklist?
503 if ( matchesPattern( remotePath, connector.getBlacklist() ) )
505 getLogger().debug( "Path [" + remotePath + "] is part of blacklist (skipping transfer from repository [" +
506 remoteRepository.getRepository().getName() + "])." );
510 // Handle pre-download policy
513 validatePolicies( this.preDownloadPolicies, connector.getPolicies(), requestProperties, localFile );
515 catch ( PolicyViolationException e )
517 String emsg = "Transfer not attempted on " + url + " : " + e.getMessage();
518 if ( fileExists( localFile ) )
520 getLogger().info( emsg + ": using already present local file." );
524 getLogger().info( emsg );
531 RepositoryURL repoUrl = remoteRepository.getURL();
532 String protocol = repoUrl.getProtocol();
533 wagon = (Wagon) wagons.get( protocol );
536 throw new ProxyException( "Unsupported target repository protocol: " + protocol );
539 boolean connected = connectToRepository( connector, wagon, remoteRepository );
542 localFile = transferSimpleFile( wagon, remoteRepository, remotePath, localFile );
544 transferChecksum( wagon, remoteRepository, remotePath, localFile, ".sha1" );
545 transferChecksum( wagon, remoteRepository, remotePath, localFile, ".md5" );
548 catch ( NotFoundException e )
550 // Do not cache url here.
553 catch ( NotModifiedException e )
555 // Do not cache url here.
558 catch ( ProxyException e )
560 urlFailureCache.cacheFailure( url );
571 catch ( ConnectionException e )
573 getLogger().warn( "Unable to disconnect wagon.", e );
578 // Handle post-download policies.
581 validatePolicies( this.postDownloadPolicies, connector.getPolicies(), requestProperties, localFile );
583 catch ( PolicyViolationException e )
585 getLogger().info( "Transfer invalidated from " + url + " : " + e.getMessage() );
586 if ( fileExists( localFile ) )
594 // Just-in-time update of the index and database by executing the consumers for this artifact
595 consumers.executeConsumers( connector.getSourceRepository().getRepository(), localFile );
597 // Everything passes.
603 * Quietly transfer the checksum file from the remote repository to the local file.
606 * @param wagon the wagon instance (should already be connected) to use.
607 * @param remoteRepository the remote repository to transfer from.
608 * @param remotePath the remote path to the resource to get.
609 * @param localFile the local file that should contain the downloaded contents
610 * @param type the type of checksum to transfer (example: ".md5" or ".sha1")
611 * @throws ProxyException if copying the downloaded file into place did not succeed.
613 private void transferChecksum( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
614 File localFile, String type )
615 throws ProxyException
617 String url = remoteRepository.getURL().getUrl() + remotePath;
619 // Transfer checksum does not use the policy.
620 if ( urlFailureCache.hasFailedBefore( url + type ) )
627 File hashFile = new File( localFile.getAbsolutePath() + type );
628 transferSimpleFile( wagon, remoteRepository, remotePath + type, hashFile );
629 getLogger().debug( "Checksum" + type + " Downloaded: " + hashFile );
631 catch ( NotFoundException e )
633 getLogger().debug( "Transfer failed, checksum not found: " + url );
634 // Consume it, do not pass this on.
636 catch ( NotModifiedException e )
638 getLogger().debug( "Transfer skipped, checksum not modified: " + url );
639 // Consume it, do not pass this on.
641 catch ( ProxyException e )
643 urlFailureCache.cacheFailure( url + type );
644 getLogger().warn( "Transfer failed on checksum: " + url + " : " + e.getMessage(), e );
645 // Critical issue, pass it on.
651 * Perform the transfer of the remote file to the local file specified.
653 * @param wagon the wagon instance to use.
654 * @param remoteRepository the remote repository to use
655 * @param remotePath the remote path to attempt to get
656 * @param localFile the local file to save to
657 * @return The local file that was transfered.
658 * @throws ProxyException if there was a problem moving the downloaded file into place.
659 * @throws WagonException if there was a problem tranfering the file.
661 private File transferSimpleFile( Wagon wagon, RemoteRepositoryContent remoteRepository, String remotePath,
663 throws ProxyException
665 assert ( remotePath != null );
667 // Transfer the file.
672 temp = new File( localFile.getAbsolutePath() + ".tmp" );
674 boolean success = false;
676 if ( !localFile.exists() )
678 getLogger().debug( "Retrieving " + remotePath + " from " + remoteRepository.getRepository().getName() );
679 wagon.get( remotePath, temp );
684 moveTempToTarget( temp, localFile );
687 // You wouldn't get here on failure, a WagonException would have been thrown.
688 getLogger().debug( "Downloaded successfully." );
692 getLogger().debug( "Retrieving " + remotePath + " from " + remoteRepository.getRepository().getName()
694 success = wagon.getIfNewer( remotePath, temp, localFile.lastModified() );
697 throw new NotModifiedException( "Not downloaded, as local file is newer than remote side: "
698 + localFile.getAbsolutePath() );
703 getLogger().debug( "Downloaded successfully." );
704 moveTempToTarget( temp, localFile );
710 catch ( ResourceDoesNotExistException e )
712 throw new NotFoundException( "Resource [" + remoteRepository.getURL() + "/" + remotePath
713 + "] does not exist: " + e.getMessage(), e );
715 catch ( WagonException e )
717 throw new ProxyException( "Download failure on resource [" + remoteRepository.getURL() + "/" + remotePath + "]:"
718 + e.getMessage(), e );
730 * Apply the policies.
732 * @param policies the map of policies to execute. (Map of String policy keys, to {@link DownloadPolicy} objects)
733 * @param settings the map of settings for the policies to execute. (Map of String policy keys, to String policy setting)
734 * @param request the request properties (utilized by the {@link DownloadPolicy#applyPolicy(String,Properties,File)})
735 * @param localFile the local file (utilized by the {@link DownloadPolicy#applyPolicy(String,Properties,File)})
737 private void validatePolicies( Map<String, ? extends DownloadPolicy> policies, Map<String, String> settings,
738 Properties request, File localFile )
739 throws PolicyViolationException
741 for ( Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() )
743 String key = (String) entry.getKey();
744 DownloadPolicy policy = entry.getValue();
745 String defaultSetting = policy.getDefaultOption();
746 String setting = StringUtils.defaultString( (String) settings.get( key ), defaultSetting );
748 getLogger().debug( "Applying [" + key + "] policy with [" + setting + "]" );
751 policy.applyPolicy( setting, request, localFile );
753 catch ( PolicyConfigurationException e )
755 getLogger().error( e.getMessage(), e );
761 * Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles
762 * its downloaded files.
764 * @param temp The completed download file
765 * @param target The final location of the downloaded file
766 * @throws ProxyException when the temp file cannot replace the target file
768 private void moveTempToTarget( File temp, File target )
769 throws ProxyException
771 if ( target.exists() && !target.delete() )
773 throw new ProxyException( "Unable to overwrite existing target file: " + target.getAbsolutePath() );
776 if ( !temp.renameTo( target ) )
778 getLogger().warn( "Unable to rename tmp file to its final name... resorting to copy command." );
782 FileUtils.copyFile( temp, target );
784 catch ( IOException e )
786 throw new ProxyException( "Cannot copy tmp file to its final location", e );
796 * Using wagon, connect to the remote repository.
798 * @param connector the connector configuration to utilize (for obtaining network proxy configuration from)
799 * @param wagon the wagon instance to establish the connection on.
800 * @param remoteRepository the remote repository to connect to.
801 * @return true if the connection was successful. false if not connected.
803 private boolean connectToRepository( ProxyConnector connector, Wagon wagon, RemoteRepositoryContent remoteRepository )
805 boolean connected = false;
807 ProxyInfo networkProxy = null;
808 synchronized ( this.networkProxyMap )
810 networkProxy = (ProxyInfo) this.networkProxyMap.get( connector.getProxyId() );
815 AuthenticationInfo authInfo = null;
816 String username = remoteRepository.getRepository().getUsername();
817 String password = remoteRepository.getRepository().getPassword();
819 if ( StringUtils.isNotBlank( username ) && StringUtils.isNotBlank( password ) )
821 getLogger().debug( "Using username " + username + " to connect to remote repository "
822 + remoteRepository.getURL() );
823 authInfo = new AuthenticationInfo();
824 authInfo.setUserName( username );
825 authInfo.setPassword( password );
829 getLogger().debug( "No authentication for remote repository needed" );
832 Repository wagonRepository = new Repository( remoteRepository.getId(), remoteRepository.getURL().toString() );
833 if ( networkProxy != null )
835 wagon.connect( wagonRepository, authInfo, networkProxy );
839 wagon.connect( wagonRepository, authInfo );
843 catch ( ConnectionException e )
846 "Could not connect to " + remoteRepository.getRepository().getName() + ": "
850 catch ( AuthenticationException e )
853 "Could not connect to " + remoteRepository.getRepository().getName() + ": "
862 * Tests whitelist and blacklist patterns against path.
864 * @param path the path to test.
865 * @param patterns the list of patterns to check.
866 * @return true if the path matches at least 1 pattern in the provided patterns list.
868 private boolean matchesPattern( String path, List<String> patterns )
870 if ( CollectionUtils.isEmpty( patterns ) )
875 for ( String pattern : patterns )
877 if ( SelectorUtils.matchPath( pattern, path, false ) )
887 * TODO: Ensure that list is correctly ordered based on configuration. See MRM-477
889 public List<ProxyConnector> getProxyConnectors( ManagedRepositoryContent repository )
891 synchronized ( this.proxyConnectorMap )
893 List<ProxyConnector> ret = (List<ProxyConnector>) this.proxyConnectorMap.get( repository.getId() );
896 return Collections.EMPTY_LIST;
899 Collections.sort( ret, ProxyConnectorOrderComparator.getInstance() );
904 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
906 if ( ConfigurationNames.isNetworkProxy( propertyName )
907 || ConfigurationNames.isManagedRepositories( propertyName )
908 || ConfigurationNames.isRemoteRepositories( propertyName )
909 || ConfigurationNames.isProxyConnector( propertyName ) )
911 initConnectorsAndNetworkProxies();
915 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
920 private void initConnectorsAndNetworkProxies()
922 synchronized ( this.proxyConnectorMap )
924 ProxyConnectorOrderComparator proxyOrderSorter = new ProxyConnectorOrderComparator();
925 this.proxyConnectorMap.clear();
927 List<ProxyConnectorConfiguration> proxyConfigs = archivaConfiguration.getConfiguration()
928 .getProxyConnectors();
929 for ( ProxyConnectorConfiguration proxyConfig : proxyConfigs )
931 String key = proxyConfig.getSourceRepoId();
935 // Create connector object.
936 ProxyConnector connector = new ProxyConnector();
938 connector.setSourceRepository( repositoryFactory.getManagedRepositoryContent( proxyConfig
939 .getSourceRepoId() ) );
940 connector.setTargetRepository( repositoryFactory.getRemoteRepositoryContent( proxyConfig
941 .getTargetRepoId() ) );
943 connector.setProxyId( proxyConfig.getProxyId() );
944 connector.setPolicies( proxyConfig.getPolicies() );
945 connector.setOrder( proxyConfig.getOrder() );
947 // Copy any blacklist patterns.
948 List<String> blacklist = new ArrayList<String>();
949 if ( CollectionUtils.isNotEmpty( proxyConfig.getBlackListPatterns() ) )
951 blacklist.addAll( proxyConfig.getBlackListPatterns() );
953 connector.setBlacklist( blacklist );
955 // Copy any whitelist patterns.
956 List<String> whitelist = new ArrayList<String>();
957 if ( CollectionUtils.isNotEmpty( proxyConfig.getWhiteListPatterns() ) )
959 whitelist.addAll( proxyConfig.getWhiteListPatterns() );
961 connector.setWhitelist( whitelist );
963 // Get other connectors
964 List<ProxyConnector> connectors = this.proxyConnectorMap.get( key );
965 if ( connectors == null )
967 // Create if we are the first.
968 connectors = new ArrayList<ProxyConnector>();
971 // Add the connector.
972 connectors.add( connector );
974 // Ensure the list is sorted.
975 Collections.sort( connectors, proxyOrderSorter );
977 // Set the key to the list of connectors.
978 this.proxyConnectorMap.put( key, connectors );
980 catch ( RepositoryNotFoundException e )
982 getLogger().warn( "Unable to use proxy connector: " + e.getMessage(), e );
984 catch ( RepositoryException e )
986 getLogger().warn( "Unable to use proxy connector: " + e.getMessage(), e );
992 synchronized ( this.networkProxyMap )
994 this.networkProxyMap.clear();
996 List<NetworkProxyConfiguration> networkProxies = archivaConfiguration.getConfiguration()
997 .getNetworkProxies();
998 for ( NetworkProxyConfiguration networkProxyConfig : networkProxies )
1000 String key = networkProxyConfig.getId();
1002 ProxyInfo proxy = new ProxyInfo();
1004 proxy.setType( networkProxyConfig.getProtocol() );
1005 proxy.setHost( networkProxyConfig.getHost() );
1006 proxy.setPort( networkProxyConfig.getPort() );
1007 proxy.setUserName( networkProxyConfig.getUsername() );
1008 proxy.setPassword( networkProxyConfig.getPassword() );
1010 this.networkProxyMap.put( key, proxy );
1015 public void initialize()
1016 throws InitializationException
1018 initConnectorsAndNetworkProxies();
1019 archivaConfiguration.addChangeListener( this );