1 package org.apache.archiva.scheduler.indexing;
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import org.apache.archiva.admin.model.beans.NetworkProxy;
22 import org.apache.archiva.admin.model.beans.RemoteRepository;
23 import org.apache.archiva.proxy.common.WagonFactory;
24 import org.apache.archiva.proxy.common.WagonFactoryException;
25 import org.apache.commons.io.FileUtils;
26 import org.apache.maven.index.NexusIndexer;
27 import org.apache.maven.index.context.IndexingContext;
28 import org.apache.maven.index.updater.IndexUpdateRequest;
29 import org.apache.maven.index.updater.IndexUpdater;
30 import org.apache.maven.index.updater.ResourceFetcher;
31 import org.apache.maven.wagon.ConnectionException;
32 import org.apache.maven.wagon.ResourceDoesNotExistException;
33 import org.apache.maven.wagon.TransferFailedException;
34 import org.apache.maven.wagon.Wagon;
35 import org.apache.maven.wagon.authentication.AuthenticationException;
36 import org.apache.maven.wagon.authentication.AuthenticationInfo;
37 import org.apache.maven.wagon.authorization.AuthorizationException;
38 import org.apache.maven.wagon.events.TransferEvent;
39 import org.apache.maven.wagon.events.TransferListener;
40 import org.apache.maven.wagon.proxy.ProxyInfo;
41 import org.apache.maven.wagon.repository.Repository;
42 import org.apache.maven.wagon.shared.http.HttpConfiguration;
43 import org.apache.maven.wagon.shared.http.HttpMethodConfiguration;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
48 import java.io.FileInputStream;
49 import java.io.FileNotFoundException;
50 import java.io.IOException;
51 import java.io.InputStream;
52 import java.lang.reflect.Method;
53 import java.net.MalformedURLException;
55 import java.util.Arrays;
56 import java.util.List;
59 * @author Olivier Lamy
62 public class DownloadRemoteIndexTask
65 private Logger log = LoggerFactory.getLogger( getClass() );
67 private RemoteRepository remoteRepository;
69 private NexusIndexer nexusIndexer;
71 private WagonFactory wagonFactory;
73 private NetworkProxy networkProxy;
75 private boolean fullDownload;
77 private List<String> runningRemoteDownloadIds;
79 private IndexUpdater indexUpdater;
81 public DownloadRemoteIndexTask( DownloadRemoteIndexTaskRequest downloadRemoteIndexTaskRequest,
82 List<String> runningRemoteDownloadIds )
84 this.remoteRepository = downloadRemoteIndexTaskRequest.getRemoteRepository();
85 this.nexusIndexer = downloadRemoteIndexTaskRequest.getNexusIndexer();
86 this.wagonFactory = downloadRemoteIndexTaskRequest.getWagonFactory();
87 this.networkProxy = downloadRemoteIndexTaskRequest.getNetworkProxy();
88 this.fullDownload = downloadRemoteIndexTaskRequest.isFullDownload();
89 this.runningRemoteDownloadIds = runningRemoteDownloadIds;
90 this.indexUpdater = downloadRemoteIndexTaskRequest.getIndexUpdater();
96 // so short lock : not sure we need it
97 synchronized ( this.runningRemoteDownloadIds )
99 if ( this.runningRemoteDownloadIds.contains( this.remoteRepository.getId() ) )
101 // skip it as it's running
102 log.info( "skip download index remote for repo {} it's already running",
103 this.remoteRepository.getId() );
106 log.info( "start download remote index for remote repository " + this.remoteRepository.getId() );
107 this.runningRemoteDownloadIds.add( this.remoteRepository.getId() );
109 IndexingContext indexingContext =
110 nexusIndexer.getIndexingContexts().get( "remote-" + remoteRepository.getId() );
112 // TODO check if null ? normally not as created by DefaultDownloadRemoteIndexScheduler#startup
114 // create a temp directory to download files
115 final File tempIndexDirectory = new File( indexingContext.getIndexDirectoryFile().getParent(), ".tmpIndex" );
118 if ( tempIndexDirectory.exists() )
120 FileUtils.deleteDirectory( tempIndexDirectory );
122 tempIndexDirectory.mkdirs();
123 String baseIndexUrl = indexingContext.getIndexUpdateUrl();
125 final Wagon wagon = wagonFactory.getWagon( new URL( this.remoteRepository.getUrl() ).getProtocol() );
126 setupWagonReadTimeout( wagon );
128 // TODO transferListener
129 wagon.addTransferListener( new DownloadListener() );
130 ProxyInfo proxyInfo = null;
131 if ( this.networkProxy != null )
133 proxyInfo = new ProxyInfo();
134 proxyInfo.setHost( this.networkProxy.getHost() );
135 proxyInfo.setPort( this.networkProxy.getPort() );
136 proxyInfo.setUserName( this.networkProxy.getUsername() );
137 proxyInfo.setPassword( this.networkProxy.getPassword() );
139 AuthenticationInfo authenticationInfo = null;
140 if ( this.remoteRepository.getUserName() != null )
142 authenticationInfo = new AuthenticationInfo();
143 authenticationInfo.setUserName( this.remoteRepository.getUserName() );
144 authenticationInfo.setPassword( this.remoteRepository.getPassword() );
146 wagon.connect( new Repository( this.remoteRepository.getId(), baseIndexUrl ), authenticationInfo,
149 File indexDirectory = indexingContext.getIndexDirectoryFile();
150 if ( !indexDirectory.exists() )
152 indexDirectory.mkdirs();
155 ResourceFetcher resourceFetcher = new ResourceFetcher()
157 public void connect( String id, String url )
163 public void disconnect()
169 public InputStream retrieve( String name )
170 throws IOException, FileNotFoundException
174 log.debug( "resourceFetcher#retrieve, name:{}", name );
175 //TODO check those files are deleted !!
176 File file = new File( tempIndexDirectory, name );
181 //file.deleteOnExit();
182 wagon.get( name, file );
183 return new FileInputStream( file );
185 catch ( AuthorizationException e )
187 throw new IOException( e.getMessage(), e );
189 catch ( TransferFailedException e )
191 throw new IOException( e.getMessage(), e );
193 catch ( ResourceDoesNotExistException e )
195 throw new FileNotFoundException( e.getMessage() );
200 IndexUpdateRequest request = new IndexUpdateRequest( indexingContext, resourceFetcher );
201 request.setForceFullUpdate( this.fullDownload );
203 this.indexUpdater.fetchAndUpdateIndex( request );
207 catch ( MalformedURLException e )
209 log.error( e.getMessage(), e );
210 throw new RuntimeException( e.getMessage(), e );
212 catch ( WagonFactoryException e )
214 log.error( e.getMessage(), e );
215 throw new RuntimeException( e.getMessage(), e );
217 catch ( ConnectionException e )
219 log.error( e.getMessage(), e );
220 throw new RuntimeException( e.getMessage(), e );
222 catch ( AuthenticationException e )
224 log.error( e.getMessage(), e );
225 throw new RuntimeException( e.getMessage(), e );
227 catch ( IOException e )
229 log.error( e.getMessage(), e );
230 throw new RuntimeException( e.getMessage(), e );
234 deleteDirectoryQuiet( tempIndexDirectory );
235 this.runningRemoteDownloadIds.remove( this.remoteRepository.getId() );
237 log.info( "end download remote index for remote repository " + this.remoteRepository.getId() );
240 private void deleteDirectoryQuiet( File f )
244 FileUtils.deleteDirectory( f );
246 catch ( IOException e )
248 log.warn( "skip error delete " + f + ": " + e.getMessage() );
252 private void setupWagonReadTimeout( Wagon wagon )
256 HttpConfiguration httpConfiguration = new HttpConfiguration().setAll(
257 new HttpMethodConfiguration().setReadTimeout( remoteRepository.getRemoteDownloadTimeout() ) );
258 Method setHttpConfigurationMethod =
259 wagon.getClass().getMethod( "setHttpConfiguration", HttpConfiguration.class );
260 setHttpConfigurationMethod.invoke( wagon, httpConfiguration );
262 catch ( Exception e )
264 log.debug( "unable to set download remote time out for index {}", e.getMessage(), e );
269 public static class DownloadListener
270 implements TransferListener
272 private Logger log = LoggerFactory.getLogger( getClass() );
274 public void transferInitiated( TransferEvent transferEvent )
276 log.debug( "initiate transfer of {}", transferEvent.getResource().getName() );
279 public void transferStarted( TransferEvent transferEvent )
281 log.debug( "start transfer of {}", transferEvent.getResource().getName() );
284 public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
286 log.debug( "transfer of {} : {}/{}",
287 Arrays.asList( transferEvent.getResource().getName(), buffer.length, length ).toArray() );
290 public void transferCompleted( TransferEvent transferEvent )
292 log.info( "end of transfer file " + transferEvent.getResource().getName() );
295 public void transferError( TransferEvent transferEvent )
297 log.info( "error of transfer file {}: {}", Arrays.asList( transferEvent.getResource().getName(),
298 transferEvent.getException().getMessage() ).toArray(
299 new Object[2] ), transferEvent.getException() );
302 public void debug( String message )
304 log.debug( "transfer debug {}", message );