]> source.dussan.org Git - archiva.git/blob
7aeb6fe569acc6fc9ef4b8369bfa210742c377a3
[archiva.git] /
1 package org.apache.archiva.scheduler.indexing;
2 /*
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
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
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
18  * under the License.
19  */
20
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;
46
47 import java.io.File;
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;
54 import java.net.URL;
55 import java.util.Arrays;
56 import java.util.List;
57
58 /**
59  * @author Olivier Lamy
60  * @since 1.4
61  */
62 public class DownloadRemoteIndexTask
63     implements Runnable
64 {
65     private Logger log = LoggerFactory.getLogger( getClass() );
66
67     private RemoteRepository remoteRepository;
68
69     private NexusIndexer nexusIndexer;
70
71     private WagonFactory wagonFactory;
72
73     private NetworkProxy networkProxy;
74
75     private boolean fullDownload;
76
77     private List<String> runningRemoteDownloadIds;
78
79     private IndexUpdater indexUpdater;
80
81     public DownloadRemoteIndexTask( DownloadRemoteIndexTaskRequest downloadRemoteIndexTaskRequest,
82                                     List<String> runningRemoteDownloadIds )
83     {
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();
91     }
92
93     public void run()
94     {
95
96         // so short lock : not sure we need it
97         synchronized ( this.runningRemoteDownloadIds )
98         {
99             if ( this.runningRemoteDownloadIds.contains( this.remoteRepository.getId() ) )
100             {
101                 // skip it as it's running
102                 log.info( "skip download index remote for repo {} it's already running",
103                           this.remoteRepository.getId() );
104                 return;
105             }
106             log.info( "start download remote index for remote repository " + this.remoteRepository.getId() );
107             this.runningRemoteDownloadIds.add( this.remoteRepository.getId() );
108         }
109         IndexingContext indexingContext =
110             nexusIndexer.getIndexingContexts().get( "remote-" + remoteRepository.getId() );
111
112         // TODO check if null ? normally not as created by DefaultDownloadRemoteIndexScheduler#startup
113
114         // create a temp directory to download files
115         final File tempIndexDirectory = new File( indexingContext.getIndexDirectoryFile().getParent(), ".tmpIndex" );
116         try
117         {
118             if ( tempIndexDirectory.exists() )
119             {
120                 FileUtils.deleteDirectory( tempIndexDirectory );
121             }
122             tempIndexDirectory.mkdirs();
123             String baseIndexUrl = indexingContext.getIndexUpdateUrl();
124
125             final Wagon wagon = wagonFactory.getWagon( new URL( this.remoteRepository.getUrl() ).getProtocol() );
126             setupWagonReadTimeout( wagon );
127
128             // TODO transferListener
129             wagon.addTransferListener( new DownloadListener() );
130             ProxyInfo proxyInfo = null;
131             if ( this.networkProxy != null )
132             {
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() );
138             }
139             AuthenticationInfo authenticationInfo = null;
140             if ( this.remoteRepository.getUserName() != null )
141             {
142                 authenticationInfo = new AuthenticationInfo();
143                 authenticationInfo.setUserName( this.remoteRepository.getUserName() );
144                 authenticationInfo.setPassword( this.remoteRepository.getPassword() );
145             }
146             wagon.connect( new Repository( this.remoteRepository.getId(), baseIndexUrl ), authenticationInfo,
147                            proxyInfo );
148
149             File indexDirectory = indexingContext.getIndexDirectoryFile();
150             if ( !indexDirectory.exists() )
151             {
152                 indexDirectory.mkdirs();
153             }
154
155             ResourceFetcher resourceFetcher = new ResourceFetcher()
156             {
157                 public void connect( String id, String url )
158                     throws IOException
159                 {
160                     //no op
161                 }
162
163                 public void disconnect()
164                     throws IOException
165                 {
166                     // no op
167                 }
168
169                 public InputStream retrieve( String name )
170                     throws IOException, FileNotFoundException
171                 {
172                     try
173                     {
174                         log.debug( "resourceFetcher#retrieve, name:{}", name );
175                         //TODO check those files are deleted !!
176                         File file = new File( tempIndexDirectory, name );
177                         if ( file.exists() )
178                         {
179                             file.delete();
180                         }
181                         //file.deleteOnExit();
182                         wagon.get( name, file );
183                         return new FileInputStream( file );
184                     }
185                     catch ( AuthorizationException e )
186                     {
187                         throw new IOException( e.getMessage(), e );
188                     }
189                     catch ( TransferFailedException e )
190                     {
191                         throw new IOException( e.getMessage(), e );
192                     }
193                     catch ( ResourceDoesNotExistException e )
194                     {
195                         throw new FileNotFoundException( e.getMessage() );
196                     }
197                 }
198             };
199
200             IndexUpdateRequest request = new IndexUpdateRequest( indexingContext, resourceFetcher );
201             request.setForceFullUpdate( this.fullDownload );
202
203             this.indexUpdater.fetchAndUpdateIndex( request );
204
205
206         }
207         catch ( MalformedURLException e )
208         {
209             log.error( e.getMessage(), e );
210             throw new RuntimeException( e.getMessage(), e );
211         }
212         catch ( WagonFactoryException e )
213         {
214             log.error( e.getMessage(), e );
215             throw new RuntimeException( e.getMessage(), e );
216         }
217         catch ( ConnectionException e )
218         {
219             log.error( e.getMessage(), e );
220             throw new RuntimeException( e.getMessage(), e );
221         }
222         catch ( AuthenticationException e )
223         {
224             log.error( e.getMessage(), e );
225             throw new RuntimeException( e.getMessage(), e );
226         }
227         catch ( IOException e )
228         {
229             log.error( e.getMessage(), e );
230             throw new RuntimeException( e.getMessage(), e );
231         }
232         finally
233         {
234             deleteDirectoryQuiet( tempIndexDirectory );
235             this.runningRemoteDownloadIds.remove( this.remoteRepository.getId() );
236         }
237         log.info( "end download remote index for remote repository " + this.remoteRepository.getId() );
238     }
239
240     private void deleteDirectoryQuiet( File f )
241     {
242         try
243         {
244             FileUtils.deleteDirectory( f );
245         }
246         catch ( IOException e )
247         {
248             log.warn( "skip error delete " + f + ": " + e.getMessage() );
249         }
250     }
251
252     private void setupWagonReadTimeout( Wagon wagon )
253     {
254         try
255         {
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 );
261         }
262         catch ( Exception e )
263         {
264             log.debug( "unable to set download remote time out for index {}", e.getMessage(), e );
265         }
266     }
267
268
269     public static class DownloadListener
270         implements TransferListener
271     {
272         private Logger log = LoggerFactory.getLogger( getClass() );
273
274         public void transferInitiated( TransferEvent transferEvent )
275         {
276             log.debug( "initiate transfer of {}", transferEvent.getResource().getName() );
277         }
278
279         public void transferStarted( TransferEvent transferEvent )
280         {
281             log.debug( "start transfer of {}", transferEvent.getResource().getName() );
282         }
283
284         public void transferProgress( TransferEvent transferEvent, byte[] buffer, int length )
285         {
286             log.debug( "transfer of {} : {}/{}",
287                        Arrays.asList( transferEvent.getResource().getName(), buffer.length, length ).toArray() );
288         }
289
290         public void transferCompleted( TransferEvent transferEvent )
291         {
292             log.info( "end of transfer file " + transferEvent.getResource().getName() );
293         }
294
295         public void transferError( TransferEvent transferEvent )
296         {
297             log.info( "error of transfer file {}: {}", Arrays.asList( transferEvent.getResource().getName(),
298                                                                       transferEvent.getException().getMessage() ).toArray(
299                 new Object[2] ), transferEvent.getException() );
300         }
301
302         public void debug( String message )
303         {
304             log.debug( "transfer debug {}", message );
305         }
306     }
307
308 }