]> source.dussan.org Git - archiva.git/blob
e5f1fcddf2be0ce356c245e96ffe4d0f93f6e79e
[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.repositories.ActiveManagedRepositories;
25 import org.apache.maven.archiva.scheduler.task.DataRefreshTask;
26 import org.apache.maven.archiva.scheduler.task.RepositoryTask;
27 import org.codehaus.plexus.logging.AbstractLogEnabled;
28 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
29 import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
30 import org.codehaus.plexus.personality.plexus.lifecycle.phase.StoppingException;
31 import org.codehaus.plexus.registry.Registry;
32 import org.codehaus.plexus.registry.RegistryListener;
33 import org.codehaus.plexus.scheduler.Scheduler;
34 import org.codehaus.plexus.taskqueue.TaskQueue;
35 import org.codehaus.plexus.taskqueue.TaskQueueException;
36 import org.codehaus.plexus.taskqueue.execution.TaskExecutionException;
37 import org.quartz.CronTrigger;
38 import org.quartz.JobDataMap;
39 import org.quartz.JobDetail;
40 import org.quartz.SchedulerException;
41
42 import java.text.ParseException;
43
44 /**
45  * Default implementation of a scheduling component for the application.
46  *
47  * @author <a href="mailto:brett@apache.org">Brett Porter</a>
48  * @plexus.component role="org.apache.maven.archiva.scheduler.RepositoryTaskScheduler"
49  */
50 public class DefaultRepositoryTaskScheduler
51     extends AbstractLogEnabled
52     implements RepositoryTaskScheduler, Startable, RegistryListener
53 {
54     /**
55      * @plexus.requirement
56      */
57     private Scheduler scheduler;
58
59     /**
60      * @plexus.requirement role-hint="data-refresh"
61      */
62     private TaskQueue datarefreshQueue;
63
64     /**
65      * @plexus.requirement
66      */
67     private ArchivaConfiguration archivaConfiguration;
68     
69     /**
70      * @plexus.requirement
71      */
72     private ActiveManagedRepositories activeRepositories;
73
74     private static final String DISCOVERER_GROUP = "DISCOVERER";
75
76     private static final String DATA_REFRESH_JOB = "dataRefreshTask";
77
78     public void start()
79         throws StartingException
80     {
81         Configuration configuration = archivaConfiguration.getConfiguration();
82         archivaConfiguration.addChangeListener( this );
83
84         try
85         {
86             scheduleJobs( configuration.getDataRefreshCronExpression() );
87         }
88         catch ( ParseException e )
89         {
90             throw new StartingException( "Invalid configuration: " + configuration.getDataRefreshCronExpression(), e );
91         }
92         catch ( SchedulerException e )
93         {
94             throw new StartingException( "Unable to start scheduler: " + e.getMessage(), e );
95         }
96     }
97
98     private void scheduleJobs( String indexerCronExpression )
99         throws ParseException, SchedulerException
100     {
101         JobDetail jobDetail = createJobDetail( DATA_REFRESH_JOB );
102
103         getLogger().info( "Scheduling data-refresh: " + indexerCronExpression );
104         CronTrigger trigger = new CronTrigger( DATA_REFRESH_JOB + "Trigger", DISCOVERER_GROUP, indexerCronExpression );
105         scheduler.scheduleJob( jobDetail, trigger );
106
107         try
108         {
109             queueNowIfNeeded();
110         }
111         catch ( org.codehaus.plexus.taskqueue.execution.TaskExecutionException e )
112         {
113             getLogger().error( "Error executing task first time, continuing anyway: " + e.getMessage(), e );
114         }
115     }
116
117     private JobDetail createJobDetail( String jobName )
118     {
119         JobDetail jobDetail = new JobDetail( jobName, DISCOVERER_GROUP, RepositoryTaskJob.class );
120
121         JobDataMap dataMap = new JobDataMap();
122         dataMap.put( RepositoryTaskJob.TASK_QUEUE, datarefreshQueue );
123         dataMap.put( RepositoryTaskJob.TASK_QUEUE_POLICY, RepositoryTask.QUEUE_POLICY_SKIP );
124         jobDetail.setJobDataMap( dataMap );
125
126         return jobDetail;
127     }
128
129     public void stop()
130         throws StoppingException
131     {
132         try
133         {
134             scheduler.unscheduleJob( DATA_REFRESH_JOB, DISCOVERER_GROUP );
135         }
136         catch ( SchedulerException e )
137         {
138             throw new StoppingException( "Unable to unschedule tasks", e );
139         }
140     }
141
142
143     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
144     {
145         // nothing to do
146     }
147
148     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
149     {
150         if ( "dataRefreshCronExpression".equals( propertyName ) )
151         {
152             getLogger().debug( "Restarting task scheduler with new configuration after property change: " +
153                 propertyName + " to " + propertyValue );
154             try
155             {
156                 stop();
157             }
158             catch ( StoppingException e )
159             {
160                 getLogger().warn( "Error stopping task scheduler: " + e.getMessage(), e );
161             }
162
163             try
164             {
165                 Configuration configuration = archivaConfiguration.getConfiguration();
166                 scheduleJobs( configuration.getDataRefreshCronExpression() );
167             }
168             catch ( ParseException e )
169             {
170                 getLogger().error(
171                     "Error restarting task scheduler after configuration change, due to configuration error: " +
172                         e.getMessage(), e );
173             }
174             catch ( SchedulerException e )
175             {
176                 getLogger().error( "Error restarting task scheduler after configuration change: " + e.getMessage(), e );
177             }
178         }
179         else
180         {
181             getLogger().debug(
182                 "Not restarting task scheduler with new configuration after property change: " + propertyName );
183         }
184     }
185
186     public void runDataRefresh()
187         throws TaskExecutionException
188     {
189         DataRefreshTask task = new DataRefreshTask();
190         task.setJobName( "DATA_REFRESH_INIT" );
191         try
192         {
193             datarefreshQueue.put( task );
194         }
195         catch ( TaskQueueException e )
196         {
197             throw new TaskExecutionException( e.getMessage(), e );
198         }
199     }
200
201     public void queueNowIfNeeded()
202         throws TaskExecutionException
203     {
204         if ( activeRepositories.needsDataRefresh() )
205         {
206             runDataRefresh();
207         }
208     }
209
210 }