]> source.dussan.org Git - archiva.git/blob
2ea5311c9d4c43635547524122e82cbf3c4a0633
[archiva.git] /
1 package org.apache.maven.archiva.scheduled;
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.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;
43
44 import java.text.ParseException;
45 import java.util.Iterator;
46 import java.util.List;
47
48 /**
49  * Default implementation of a scheduling component for archiva..
50  *
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"
54  */
55 public class DefaultArchivaTaskScheduler
56     extends AbstractLogEnabled
57     implements ArchivaTaskScheduler, Startable, RegistryListener
58 {
59     /**
60      * @plexus.requirement
61      */
62     private Scheduler scheduler;
63
64    
65     /**
66      * @plexus.requirement role-hint="archiva-task-queue"
67      */
68     private TaskQueue archivaTaskQueue;
69       
70     /**
71      * @plexus.requirement
72      */
73     private ArchivaConfiguration archivaConfiguration;
74   
75     
76     public static final String DATABASE_DISCOVERER_GROUP = "database-group";
77     
78     public static final String DATABASE_JOB = "database-job";
79     public static final String DATABASE_JOB_TRIGGER = "database-job-trigger";
80    
81     public static final String REPOSITORY_DISCOVERER_GROUP = "repository-group";
82     
83     public static final String REPOSITORY_JOB = "repository-job";
84     public static final String REPOSITORY_JOB_TRIGGER = "repository-job-trigger";
85     
86     public void start()
87         throws StartingException
88     {
89         try
90         {
91                 List repositories = archivaConfiguration.getConfiguration().getRepositories();
92                 
93                 for ( Iterator i = repositories.iterator(); i.hasNext(); )
94                 {
95                         RepositoryConfiguration repoConfig = (RepositoryConfiguration)i.next();
96                         
97                         scheduleRepositoryJobs( repoConfig );                   
98                 }
99                 
100                 scheduleDatabaseJobs( );
101         }
102         catch ( SchedulerException e )
103         {
104             throw new StartingException( "Unable to start scheduler: " + e.getMessage(), e );
105         }
106     }
107
108     private void scheduleRepositoryJobs( RepositoryConfiguration repoConfig )
109         throws SchedulerException
110     {
111         if ( repoConfig.getRefreshCronExpression() == null )
112         {
113             getLogger().warn( "Skipping job, no cron expression for " + repoConfig.getId() );
114             return;
115         }
116         
117         // get the cron string for these database scanning jobs
118         String cronString = repoConfig.getRefreshCronExpression();        
119         
120         // setup the unprocessed artifact job
121         JobDetail repositoryJob =
122             new JobDetail( REPOSITORY_JOB + ":" + repoConfig.getId() , REPOSITORY_DISCOVERER_GROUP, RepositoryTaskJob.class );
123
124         JobDataMap dataMap = new JobDataMap();
125         dataMap.put( RepositoryTaskJob.TASK_QUEUE, archivaTaskQueue );
126         dataMap.put( RepositoryTaskJob.TASK_REPOSITORY, repoConfig.getId() );
127         repositoryJob.setJobDataMap( dataMap );
128        
129         try 
130         {
131             CronTrigger trigger =
132                 new CronTrigger( REPOSITORY_JOB_TRIGGER + ":" + repoConfig.getId() , REPOSITORY_DISCOVERER_GROUP, cronString );
133         
134             scheduler.scheduleJob( repositoryJob, trigger );
135         }
136         catch ( ParseException e )
137         {
138             getLogger().error( "ParseException in repository scanning cron expression, disabling repository scanning for '" + repoConfig.getId() + "': " + e.getMessage() );
139         }
140              
141     }
142     
143     private void scheduleDatabaseJobs( )
144         throws SchedulerException
145     {        
146         String cronString = archivaConfiguration.getConfiguration().getDatabaseScanning().getCronExpression();
147         
148         // setup the unprocessed artifact job
149         JobDetail databaseJob =
150             new JobDetail( DATABASE_JOB, DATABASE_DISCOVERER_GROUP, DatabaseTaskJob.class );
151
152         JobDataMap dataMap = new JobDataMap();
153         dataMap.put( DatabaseTaskJob.TASK_QUEUE, archivaTaskQueue );
154         databaseJob.setJobDataMap( dataMap );
155        
156         try 
157         {
158             CronTrigger trigger =
159                 new CronTrigger( DATABASE_JOB_TRIGGER, DATABASE_DISCOVERER_GROUP, cronString );
160         
161             scheduler.scheduleJob( databaseJob, trigger );
162         }
163         catch ( ParseException e )
164         {
165             getLogger().error( "ParseException in database scanning cron expression, disabling database scanning: " + e.getMessage() );
166         }
167         
168     }
169
170     public void stop()
171         throws StoppingException
172     {
173         try
174         {
175             scheduler.unscheduleJob( DATABASE_JOB, DATABASE_DISCOVERER_GROUP );         
176         }
177         catch ( SchedulerException e )
178         {
179             throw new StoppingException( "Unable to unschedule tasks", e );
180         }
181     }
182
183
184     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
185     {
186         // nothing to do
187     }
188
189     /**
190      * 
191      */
192     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
193     {
194         // cronExpression comes from the database scanning section
195         if ( "cronExpression".equals( propertyName ) )
196         {
197             getLogger().debug( "Restarting the database scheduled task after property change: " + propertyName );
198             
199             try
200             {
201                 scheduler.unscheduleJob( DATABASE_JOB, DATABASE_DISCOVERER_GROUP );
202             
203                 scheduleDatabaseJobs();
204             }
205             catch ( SchedulerException e )
206             {
207                 getLogger().error( "Error restarting the database scanning job after property change." );
208             }
209         }
210         
211         // refreshCronExpression comes from the repositories section
212         // 
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 ) )
215         {
216             List repositories = archivaConfiguration.getConfiguration().getRepositories();
217             
218             for ( Iterator i = repositories.iterator(); i.hasNext(); )
219             {
220                 RepositoryConfiguration repoConfig = (RepositoryConfiguration)i.next();
221                 
222                 if ( repoConfig.getRefreshCronExpression() != null )
223                 {
224                     try
225                     {
226                         // unschedule handles jobs that might not exist
227                         scheduler.unscheduleJob( REPOSITORY_JOB + ":" + repoConfig.getId() , REPOSITORY_DISCOVERER_GROUP );
228                         scheduleRepositoryJobs( repoConfig );
229                     }
230                     catch ( SchedulerException e )
231                     {
232                         getLogger().error( "error restarting job: " + REPOSITORY_JOB + ":" + repoConfig.getId() );
233                     }
234                 }
235             }
236         }
237     }
238
239     public void runAllRepositoryTasks() throws TaskExecutionException
240     {
241         try
242         {
243             List repositories = archivaConfiguration.getConfiguration().getRepositories();
244             
245             for ( Iterator i = repositories.iterator(); i.hasNext(); )
246             {
247                 RepositoryConfiguration repoConfig = (RepositoryConfiguration)i.next();
248                 
249                 scheduleRepositoryJobs( repoConfig );               
250             }
251             
252         }
253         catch ( SchedulerException e )
254         {
255             throw new TaskExecutionException( "Unable to schedule repository jobs: " + e.getMessage(), e );
256         }
257     }
258
259     public void runDatabaseTasks() throws TaskExecutionException
260     {
261         try
262         {
263             scheduleDatabaseJobs();
264         }
265         catch ( SchedulerException e )
266         {
267             throw new TaskExecutionException( "Unable to schedule repository jobs: " + e.getMessage(), e );
268
269         }
270     }
271
272     public void runRepositoryTasks( String repositoryId ) throws TaskExecutionException
273     {
274         try
275         {
276             RepositoryConfiguration repoConfig = archivaConfiguration.getConfiguration().findRepositoryById( repositoryId );
277             
278             scheduleRepositoryJobs( repoConfig );                         
279         }
280         catch ( SchedulerException e )
281         {
282             throw new TaskExecutionException( "Unable to schedule repository jobs: " + e.getMessage(), e );
283         } 
284     }
285
286     
287     
288 }