This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.scheduler.repository;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.admin.model.RepositoryAdminException;
023import org.apache.archiva.admin.model.beans.ManagedRepository;
024import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
025import org.apache.archiva.metadata.repository.MetadataRepository;
026import org.apache.archiva.metadata.repository.MetadataRepositoryException;
027import org.apache.archiva.metadata.repository.RepositorySession;
028import org.apache.archiva.metadata.repository.RepositorySessionFactory;
029import org.apache.archiva.metadata.repository.stats.RepositoryStatistics;
030import org.apache.archiva.metadata.repository.stats.RepositoryStatisticsManager;
031import org.apache.archiva.repository.scanner.RepositoryContentConsumers;
032import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
033import org.apache.archiva.repository.scanner.RepositoryScanner;
034import org.apache.archiva.repository.scanner.RepositoryScannerException;
035import org.apache.archiva.scheduler.repository.model.RepositoryTask;
036import org.apache.commons.lang.StringUtils;
037import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
038import org.apache.archiva.redback.components.taskqueue.Task;
039import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutionException;
040import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutor;
041import org.slf4j.Logger;
042import org.slf4j.LoggerFactory;
043import org.springframework.stereotype.Service;
044
045import javax.annotation.PostConstruct;
046import javax.inject.Inject;
047import java.util.Date;
048
049/**
050 * ArchivaRepositoryScanningTaskExecutor
051 *
052 *
053 */
054@Service( "taskExecutor#repository-scanning" )
055public class ArchivaRepositoryScanningTaskExecutor
056    implements TaskExecutor<RepositoryTask>
057{
058    private Logger log = LoggerFactory.getLogger( ArchivaRepositoryScanningTaskExecutor.class );
059
060    @Inject
061    private ManagedRepositoryAdmin managedRepositoryAdmin;
062
063    @Inject
064    private RepositoryScanner repoScanner;
065
066    @Inject
067    private RepositoryContentConsumers consumers;
068
069    private Task task;
070
071    @Inject
072    private RepositoryStatisticsManager repositoryStatisticsManager;
073
074    /**
075     * FIXME: this could be multiple implementations and needs to be configured.
076     */
077    @Inject
078    private RepositorySessionFactory repositorySessionFactory;
079
080    @PostConstruct
081    public void initialize()
082        throws InitializationException
083    {
084        log.info( "Initialized {}", this.getClass().getName() );
085    }
086
087    @SuppressWarnings( "unchecked" )
088    @Override
089    public void executeTask( RepositoryTask task )
090        throws TaskExecutionException
091    {
092        try
093        {
094            // TODO: replace this whole class with the prescribed content scanning service/action
095            // - scan repository for artifacts that do not have corresponding metadata or have been updated and
096            // send events for each
097            // - scan metadata for artifacts that have been removed and send events for each
098            // - scan metadata for missing plugin data
099            // - store information so that it can restart upon failure (publish event on the server recovery
100            // queue, remove it on successful completion)
101
102            this.task = task;
103
104            String repoId = task.getRepositoryId();
105            if ( StringUtils.isBlank( repoId ) )
106            {
107                throw new TaskExecutionException( "Unable to execute RepositoryTask with blank repository Id." );
108            }
109
110            ManagedRepository arepo = managedRepositoryAdmin.getManagedRepository( repoId );
111
112            // execute consumers on resource file if set
113            if ( task.getResourceFile() != null )
114            {
115                log.debug( "Executing task from queue with job name: {}", task );
116                consumers.executeConsumers( arepo, task.getResourceFile(), task.isUpdateRelatedArtifacts() );
117            }
118            else
119            {
120                log.info( "Executing task from queue with job name: {}", task );
121
122                // otherwise, execute consumers on whole repository
123                if ( arepo == null )
124                {
125                    throw new TaskExecutionException(
126                        "Unable to execute RepositoryTask with invalid repository id: " + repoId );
127                }
128
129                long sinceWhen = RepositoryScanner.FRESH_SCAN;
130                long previousFileCount = 0;
131
132                RepositorySession repositorySession = repositorySessionFactory.createSession();
133                MetadataRepository metadataRepository = repositorySession.getRepository();
134                try
135                {
136                    if ( !task.isScanAll() )
137                    {
138                        RepositoryStatistics previousStats =
139                            repositoryStatisticsManager.getLastStatistics( metadataRepository, repoId );
140                        if ( previousStats != null )
141                        {
142                            sinceWhen = previousStats.getScanStartTime().getTime();
143                            previousFileCount = previousStats.getTotalFileCount();
144                        }
145                    }
146
147                    RepositoryScanStatistics stats;
148                    try
149                    {
150                        stats = repoScanner.scan( arepo, sinceWhen );
151                    }
152                    catch ( RepositoryScannerException e )
153                    {
154                        throw new TaskExecutionException( "Repository error when executing repository job.", e );
155                    }
156
157                    log.info( "Finished first scan: {}", stats.toDump( arepo ) );
158
159                    // further statistics will be populated by the following method
160                    Date endTime = new Date( stats.getWhenGathered().getTime() + stats.getDuration() );
161
162                    log.info( "Gathering repository statistics" );
163
164                    repositoryStatisticsManager.addStatisticsAfterScan( metadataRepository, repoId,
165                                                                        stats.getWhenGathered(), endTime,
166                                                                        stats.getTotalFileCount(),
167                                                                        stats.getTotalFileCount() - previousFileCount );
168                    repositorySession.save();
169                }
170                catch ( MetadataRepositoryException e )
171                {
172                    throw new TaskExecutionException( "Unable to store updated statistics: " + e.getMessage(), e );
173                }
174                finally
175                {
176                    repositorySession.close();
177                }
178
179//                log.info( "Scanning for removed repository content" );
180
181//                metadataRepository.findAllProjects();
182                // FIXME: do something
183
184                log.info( "Finished repository task: {}", task );
185
186                this.task = null;
187            }
188        }
189        catch ( RepositoryAdminException e )
190        {
191            log.error( e.getMessage(), e );
192            throw new TaskExecutionException( e.getMessage(), e );
193        }
194    }
195
196    public Task getCurrentTaskInExecution()
197    {
198        return task;
199    }
200
201    public RepositoryScanner getRepoScanner()
202    {
203        return repoScanner;
204    }
205
206    public void setRepoScanner( RepositoryScanner repoScanner )
207    {
208        this.repoScanner = repoScanner;
209    }
210
211    public RepositoryContentConsumers getConsumers()
212    {
213        return consumers;
214    }
215
216    public void setConsumers( RepositoryContentConsumers consumers )
217    {
218        this.consumers = consumers;
219    }
220
221    public RepositorySessionFactory getRepositorySessionFactory()
222    {
223        return repositorySessionFactory;
224    }
225
226    public void setRepositorySessionFactory( RepositorySessionFactory repositorySessionFactory )
227    {
228        this.repositorySessionFactory = repositorySessionFactory;
229    }
230
231    public RepositoryStatisticsManager getRepositoryStatisticsManager()
232    {
233        return repositoryStatisticsManager;
234    }
235
236    public void setRepositoryStatisticsManager( RepositoryStatisticsManager repositoryStatisticsManager )
237    {
238        this.repositoryStatisticsManager = repositoryStatisticsManager;
239    }
240
241    public ManagedRepositoryAdmin getManagedRepositoryAdmin()
242    {
243        return managedRepositoryAdmin;
244    }
245
246    public void setManagedRepositoryAdmin( ManagedRepositoryAdmin managedRepositoryAdmin )
247    {
248        this.managedRepositoryAdmin = managedRepositoryAdmin;
249    }
250}