1 package org.apache.maven.archiva.scheduled;
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.maven.archiva.configuration.ArchivaConfiguration;
23 import org.apache.maven.archiva.configuration.Configuration;
24 import org.apache.maven.archiva.configuration.RepositoryConfiguration;
25 import org.apache.maven.archiva.database.ArchivaDatabaseException;
26 import org.apache.maven.archiva.database.ObjectNotFoundException;
27 import org.apache.maven.archiva.database.RepositoryDAO;
28 import org.apache.maven.archiva.model.ArchivaRepository;
29 import org.codehaus.plexus.logging.AbstractLogEnabled;
30 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
31 import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
32 import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
33 import org.codehaus.plexus.registry.Registry;
34 import org.codehaus.plexus.registry.RegistryListener;
35 import org.codehaus.plexus.scheduler.Scheduler;
36 import org.codehaus.plexus.taskqueue.TaskQueue;
37 import org.codehaus.plexus.taskqueue.TaskQueueException;
38 import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
39 import org.quartz.CronTrigger;
40 import org.quartz.JobDataMap;
41 import org.quartz.JobDetail;
42 import org.quartz.SchedulerException;
44 import java.text.ParseException;
45 import java.util.Iterator;
46 import java.util.List;
49 * Default implementation of a scheduling component for archiva..
51 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
52 * @author <a href="mailto:jmcconnell@apache.org">Jesse McConnell</a>
53 * @plexus.component role="org.apache.maven.archiva.scheduler.ArchivaTaskScheduler"
55 public class DefaultArchivaTaskScheduler
56 extends AbstractLogEnabled
57 implements ArchivaTaskScheduler, Startable, RegistryListener
62 private Scheduler scheduler;
66 * @plexus.requirement role-hint="archiva-task-queue"
68 private TaskQueue archivaTaskQueue;
73 private ArchivaConfiguration archivaConfiguration;
76 public static final String DATABASE_DISCOVERER_GROUP = "database-group";
78 public static final String DATABASE_JOB = "database-job";
79 public static final String DATABASE_JOB_TRIGGER = "database-job-trigger";
81 public static final String REPOSITORY_DISCOVERER_GROUP = "repository-group";
83 public static final String REPOSITORY_JOB = "repository-job";
84 public static final String REPOSITORY_JOB_TRIGGER = "repository-job-trigger";
87 throws StartingException
91 List repositories = archivaConfiguration.getConfiguration().getRepositories();
93 for ( Iterator i = repositories.iterator(); i.hasNext(); )
95 RepositoryConfiguration repoConfig = (RepositoryConfiguration)i.next();
97 scheduleRepositoryJobs( repoConfig );
100 scheduleDatabaseJobs( );
102 catch ( SchedulerException e )
104 throw new StartingException( "Unable to start scheduler: " + e.getMessage(), e );
108 private void scheduleRepositoryJobs( RepositoryConfiguration repoConfig )
109 throws SchedulerException
111 if ( repoConfig.getRefreshCronExpression() == null )
113 getLogger().warn( "Skipping job, no cron expression for " + repoConfig.getId() );
117 // get the cron string for these database scanning jobs
118 String cronString = repoConfig.getRefreshCronExpression();
120 // setup the unprocessed artifact job
121 JobDetail repositoryJob =
122 new JobDetail( REPOSITORY_JOB + ":" + repoConfig.getId() , REPOSITORY_DISCOVERER_GROUP, RepositoryTaskJob.class );
124 JobDataMap dataMap = new JobDataMap();
125 dataMap.put( RepositoryTaskJob.TASK_QUEUE, archivaTaskQueue );
126 dataMap.put( RepositoryTaskJob.TASK_REPOSITORY, repoConfig.getId() );
127 repositoryJob.setJobDataMap( dataMap );
131 CronTrigger trigger =
132 new CronTrigger( REPOSITORY_JOB_TRIGGER + ":" + repoConfig.getId() , REPOSITORY_DISCOVERER_GROUP, cronString );
134 scheduler.scheduleJob( repositoryJob, trigger );
136 catch ( ParseException e )
138 getLogger().error( "ParseException in repository scanning cron expression, disabling repository scanning for '" + repoConfig.getId() + "': " + e.getMessage() );
143 private void scheduleDatabaseJobs( )
144 throws SchedulerException
146 String cronString = archivaConfiguration.getConfiguration().getDatabaseScanning().getCronExpression();
148 // setup the unprocessed artifact job
149 JobDetail databaseJob =
150 new JobDetail( DATABASE_JOB, DATABASE_DISCOVERER_GROUP, DatabaseTaskJob.class );
152 JobDataMap dataMap = new JobDataMap();
153 dataMap.put( DatabaseTaskJob.TASK_QUEUE, archivaTaskQueue );
154 databaseJob.setJobDataMap( dataMap );
158 CronTrigger trigger =
159 new CronTrigger( DATABASE_JOB_TRIGGER, DATABASE_DISCOVERER_GROUP, cronString );
161 scheduler.scheduleJob( databaseJob, trigger );
163 catch ( ParseException e )
165 getLogger().error( "ParseException in database scanning cron expression, disabling database scanning: " + e.getMessage() );
171 throws StoppingException
175 scheduler.unscheduleJob( DATABASE_JOB, DATABASE_DISCOVERER_GROUP );
177 catch ( SchedulerException e )
179 throw new StoppingException( "Unable to unschedule tasks", e );
184 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
192 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
194 // cronExpression comes from the database scanning section
195 if ( "cronExpression".equals( propertyName ) )
197 getLogger().debug( "Restarting the database scheduled task after property change: " + propertyName );
201 scheduler.unscheduleJob( DATABASE_JOB, DATABASE_DISCOVERER_GROUP );
203 scheduleDatabaseJobs();
205 catch ( SchedulerException e )
207 getLogger().error( "Error restarting the database scanning job after property change." );
211 // refreshCronExpression comes from the repositories section
213 // currently we have to reschedule all repo jobs because we don't know where the changed one came from
214 if ( "refreshCronExpression".equals( propertyName ) )
216 List repositories = archivaConfiguration.getConfiguration().getRepositories();
218 for ( Iterator i = repositories.iterator(); i.hasNext(); )
220 RepositoryConfiguration repoConfig = (RepositoryConfiguration)i.next();
222 if ( repoConfig.getRefreshCronExpression() != null )
226 // unschedule handles jobs that might not exist
227 scheduler.unscheduleJob( REPOSITORY_JOB + ":" + repoConfig.getId() , REPOSITORY_DISCOVERER_GROUP );
228 scheduleRepositoryJobs( repoConfig );
230 catch ( SchedulerException e )
232 getLogger().error( "error restarting job: " + REPOSITORY_JOB + ":" + repoConfig.getId() );
239 public void runAllRepositoryTasks() throws TaskExecutionException
243 List repositories = archivaConfiguration.getConfiguration().getRepositories();
245 for ( Iterator i = repositories.iterator(); i.hasNext(); )
247 RepositoryConfiguration repoConfig = (RepositoryConfiguration)i.next();
249 scheduleRepositoryJobs( repoConfig );
253 catch ( SchedulerException e )
255 throw new TaskExecutionException( "Unable to schedule repository jobs: " + e.getMessage(), e );
259 public void runDatabaseTasks() throws TaskExecutionException
263 scheduleDatabaseJobs();
265 catch ( SchedulerException e )
267 throw new TaskExecutionException( "Unable to schedule repository jobs: " + e.getMessage(), e );
272 public void runRepositoryTasks( String repositoryId ) throws TaskExecutionException
276 RepositoryConfiguration repoConfig = archivaConfiguration.getConfiguration().findRepositoryById( repositoryId );
278 scheduleRepositoryJobs( repoConfig );
280 catch ( SchedulerException e )
282 throw new TaskExecutionException( "Unable to schedule repository jobs: " + e.getMessage(), e );