View Javadoc

1   package org.apache.archiva.scheduler.repository;
2   
3   /*
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
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
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
19   * under the License.
20   */
21  
22  import org.apache.archiva.admin.model.RepositoryAdminException;
23  import org.apache.archiva.admin.model.beans.ManagedRepository;
24  import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
25  import org.apache.archiva.metadata.repository.MetadataRepository;
26  import org.apache.archiva.metadata.repository.MetadataRepositoryException;
27  import org.apache.archiva.metadata.repository.RepositorySession;
28  import org.apache.archiva.metadata.repository.RepositorySessionFactory;
29  import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
30  import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
31  import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
32  import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
33  import org.apache.archiva.repository.scanner.RepositoryScanner;
34  import org.apache.archiva.repository.scanner.RepositoryScannerException;
35  import org.apache.archiva.scheduler.repository.model.RepositoryTask;
36  import org.apache.commons.lang.StringUtils;
37  import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
38  import org.apache.archiva.redback.components.taskqueue.Task;
39  import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutionException;
40  import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutor;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  import org.springframework.stereotype.Service;
44  
45  import javax.annotation.PostConstruct;
46  import javax.inject.Inject;
47  import java.util.Date;
48  
49  /**
50   * ArchivaRepositoryScanningTaskExecutor
51   *
52   *
53   */
54  @Service( "taskExecutor#repository-scanning" )
55  public class ArchivaRepositoryScanningTaskExecutor
56      implements TaskExecutor
57  {
58      private Logger log = LoggerFactory.getLogger( ArchivaRepositoryScanningTaskExecutor.class );
59  
60      /**
61       *
62       */
63      @Inject
64      private ManagedRepositoryAdmin managedRepositoryAdmin;
65  
66      /**
67       * The repository scanner component.
68       */
69      @Inject
70      private RepositoryScanner repoScanner;
71  
72      /**
73       *
74       */
75      @Inject
76      private RepositoryContentConsumers consumers;
77  
78      private Task task;
79  
80      /**
81       *
82       */
83      @Inject
84      private RepositoryStatisticsManager repositoryStatisticsManager;
85  
86      /**
87       * FIXME: this could be multiple implementations and needs to be configured.
88       */
89      @Inject
90      private RepositorySessionFactory repositorySessionFactory;
91  
92      @PostConstruct
93      public void initialize()
94          throws InitializationException
95      {
96          log.info( "Initialized {}", this.getClass().getName() );
97      }
98  
99      @SuppressWarnings( "unchecked" )
100     public void executeTask( Task task )
101         throws TaskExecutionException
102     {
103         try
104         {
105             // TODO: replace this whole class with the prescribed content scanning service/action
106             // - scan repository for artifacts that do not have corresponding metadata or have been updated and
107             // send events for each
108             // - scan metadata for artifacts that have been removed and send events for each
109             // - scan metadata for missing plugin data
110             // - store information so that it can restart upon failure (publish event on the server recovery
111             // queue, remove it on successful completion)
112 
113             this.task = task;
114 
115             RepositoryTask repoTask = (RepositoryTask) task;
116 
117             String repoId = repoTask.getRepositoryId();
118             if ( StringUtils.isBlank( repoId ) )
119             {
120                 throw new TaskExecutionException( "Unable to execute RepositoryTask with blank repository Id." );
121             }
122 
123             ManagedRepository arepo = managedRepositoryAdmin.getManagedRepository( repoId );
124 
125             // execute consumers on resource file if set
126             if ( repoTask.getResourceFile() != null )
127             {
128                 log.debug( "Executing task from queue with job name: {}", repoTask );
129                 consumers.executeConsumers( arepo, repoTask.getResourceFile(), repoTask.isUpdateRelatedArtifacts() );
130             }
131             else
132             {
133                 log.info( "Executing task from queue with job name: {}", repoTask );
134 
135                 // otherwise, execute consumers on whole repository
136                 if ( arepo == null )
137                 {
138                     throw new TaskExecutionException(
139                         "Unable to execute RepositoryTask with invalid repository id: " + repoId );
140                 }
141 
142                 long sinceWhen = RepositoryScanner.FRESH_SCAN;
143                 long previousFileCount = 0;
144 
145                 RepositorySession repositorySession = repositorySessionFactory.createSession();
146                 MetadataRepository metadataRepository = repositorySession.getRepository();
147                 try
148                 {
149                     if ( !repoTask.isScanAll() )
150                     {
151                         RepositoryStatistics previousStats =
152                             repositoryStatisticsManager.getLastStatistics( metadataRepository, repoId );
153                         if ( previousStats != null )
154                         {
155                             sinceWhen = previousStats.getScanStartTime().getTime();
156                             previousFileCount = previousStats.getTotalFileCount();
157                         }
158                     }
159 
160                     RepositoryScanStatistics stats;
161                     try
162                     {
163                         stats = repoScanner.scan( arepo, sinceWhen );
164                     }
165                     catch ( RepositoryScannerException e )
166                     {
167                         throw new TaskExecutionException( "Repository error when executing repository job.", e );
168                     }
169 
170                     log.info( "Finished first scan: {}", stats.toDump( arepo ) );
171 
172                     // further statistics will be populated by the following method
173                     Date endTime = new Date( stats.getWhenGathered().getTime() + stats.getDuration() );
174 
175                     log.info( "Gathering repository statistics" );
176 
177                     repositoryStatisticsManager.addStatisticsAfterScan( metadataRepository, repoId,
178                                                                         stats.getWhenGathered(), endTime,
179                                                                         stats.getTotalFileCount(),
180                                                                         stats.getTotalFileCount() - previousFileCount );
181                     repositorySession.save();
182                 }
183                 catch ( MetadataRepositoryException e )
184                 {
185                     throw new TaskExecutionException( "Unable to store updated statistics: " + e.getMessage(), e );
186                 }
187                 finally
188                 {
189                     repositorySession.close();
190                 }
191 
192 //                log.info( "Scanning for removed repository content" );
193 
194 //                metadataRepository.findAllProjects();
195                 // FIXME: do something
196 
197                 log.info( "Finished repository task: {}", repoTask );
198 
199                 this.task = null;
200             }
201         }
202         catch ( RepositoryAdminException e )
203         {
204             log.error( e.getMessage(), e );
205             throw new TaskExecutionException( e.getMessage(), e );
206         }
207     }
208 
209     public Task getCurrentTaskInExecution()
210     {
211         return task;
212     }
213 
214     public RepositoryScanner getRepoScanner()
215     {
216         return repoScanner;
217     }
218 
219     public void setRepoScanner( RepositoryScanner repoScanner )
220     {
221         this.repoScanner = repoScanner;
222     }
223 
224     public RepositoryContentConsumers getConsumers()
225     {
226         return consumers;
227     }
228 
229     public void setConsumers( RepositoryContentConsumers consumers )
230     {
231         this.consumers = consumers;
232     }
233 
234     public RepositorySessionFactory getRepositorySessionFactory()
235     {
236         return repositorySessionFactory;
237     }
238 
239     public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
240     {
241         this.repositorySessionFactory = repositorySessionFactory;
242     }
243 
244     public RepositoryStatisticsManager getRepositoryStatisticsManager()
245     {
246         return repositoryStatisticsManager;
247     }
248 
249     public void setRepositoryStatisticsManager( RepositoryStatisticsManager repositoryStatisticsManager )
250     {
251         this.repositoryStatisticsManager = repositoryStatisticsManager;
252     }
253 
254     public ManagedRepositoryAdmin getManagedRepositoryAdmin()
255     {
256         return managedRepositoryAdmin;
257     }
258 
259     public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
260     {
261         this.managedRepositoryAdmin = managedRepositoryAdmin;
262     }
263 }