1 package org.apache.maven.continuum.build.settings;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.text.ParseException;
23 import java.util.Collection;
24 import java.util.Date;
25 import java.util.List;
26
27 import org.apache.continuum.dao.BuildDefinitionDao;
28 import org.apache.continuum.dao.DirectoryPurgeConfigurationDao;
29 import org.apache.continuum.dao.RepositoryPurgeConfigurationDao;
30 import org.apache.continuum.dao.ScheduleDao;
31 import org.apache.continuum.model.repository.DirectoryPurgeConfiguration;
32 import org.apache.continuum.model.repository.RepositoryPurgeConfiguration;
33 import org.apache.maven.continuum.Continuum;
34 import org.apache.maven.continuum.model.project.BuildDefinition;
35 import org.apache.maven.continuum.model.project.Schedule;
36 import org.apache.maven.continuum.scheduler.ContinuumBuildJob;
37 import org.apache.maven.continuum.scheduler.ContinuumPurgeJob;
38 import org.apache.maven.continuum.scheduler.ContinuumSchedulerConstants;
39 import org.apache.maven.continuum.store.ContinuumStoreException;
40 import org.codehaus.plexus.scheduler.AbstractJob;
41 import org.codehaus.plexus.scheduler.Scheduler;
42 import org.codehaus.plexus.util.StringUtils;
43 import org.quartz.CronTrigger;
44 import org.quartz.JobDataMap;
45 import org.quartz.JobDetail;
46 import org.quartz.SchedulerException;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50
51
52
53
54
55 public class DefaultSchedulesActivator
56 implements SchedulesActivator
57 {
58 private static final Logger log = LoggerFactory.getLogger( DefaultSchedulesActivator.class );
59
60
61
62
63 private DirectoryPurgeConfigurationDao directoryPurgeConfigurationDao;
64
65
66
67
68 private RepositoryPurgeConfigurationDao repositoryPurgeConfigurationDao;
69
70
71
72
73 private BuildDefinitionDao buildDefinitionDao;
74
75
76
77
78 private ScheduleDao scheduleDao;
79
80
81
82
83 private Scheduler scheduler;
84
85
86 private static final int delay = 1;
87
88 public void activateSchedules( Continuum continuum )
89 throws SchedulesActivationException
90 {
91 log.info( "Activating schedules ..." );
92
93 Collection<Schedule> schedules = scheduleDao.getAllSchedulesByName();
94
95 for ( Schedule schedule : schedules )
96 {
97 if ( schedule.isActive() )
98 {
99 try
100 {
101 activateSchedule( schedule, continuum );
102 }
103 catch ( SchedulesActivationException e )
104 {
105 log.error( "Can't activate schedule '" + schedule.getName() + "'", e );
106
107 schedule.setActive( false );
108
109 try
110 {
111 scheduleDao.storeSchedule( schedule );
112 }
113 catch ( ContinuumStoreException e1 )
114 {
115 throw new SchedulesActivationException( "Can't desactivate schedule '" + schedule.getName()
116 + "'", e );
117 }
118 }
119 }
120 }
121 }
122
123 public void activateSchedule( Schedule schedule, Continuum continuum )
124 throws SchedulesActivationException
125 {
126 if ( schedule != null )
127 {
128 log.info( "Activating schedule " + schedule.getName() );
129
130 activateBuildSchedule( schedule, continuum );
131
132 activatePurgeSchedule( schedule, continuum );
133 }
134 }
135
136 public void activateBuildSchedule( Schedule schedule, Continuum continuum )
137 throws SchedulesActivationException
138 {
139 if ( schedule != null && schedule.isActive() && isScheduleFromBuildJob( schedule ) )
140 {
141 schedule( schedule, continuum, ContinuumBuildJob.class, ContinuumBuildJob.BUILD_GROUP );
142 }
143 }
144
145 public void activatePurgeSchedule( Schedule schedule, Continuum continuum )
146 throws SchedulesActivationException
147 {
148 if ( schedule != null && schedule.isActive() && isScheduleFromPurgeJob( schedule ) )
149 {
150 schedule( schedule, continuum, ContinuumPurgeJob.class, ContinuumPurgeJob.PURGE_GROUP );
151 }
152 }
153
154 public void unactivateSchedule( Schedule schedule, Continuum continuum )
155 throws SchedulesActivationException
156 {
157 log.info( "Deactivating schedule " + schedule.getName() );
158
159 unactivateBuildSchedule( schedule );
160 unactivatePurgeSchedule( schedule );
161 }
162
163 public void unactivateOrphanBuildSchedule( Schedule schedule )
164 throws SchedulesActivationException
165 {
166 if ( schedule != null && !isScheduleFromBuildJob( schedule ) )
167 {
168 unactivateBuildSchedule( schedule );
169 }
170 }
171
172 public void unactivateOrphanPurgeSchedule( Schedule schedule )
173 throws SchedulesActivationException
174 {
175 if ( schedule != null && !isScheduleFromPurgeJob( schedule ) )
176 {
177 unactivatePurgeSchedule( schedule );
178 }
179 }
180
181 private void unactivateBuildSchedule( Schedule schedule )
182 throws SchedulesActivationException
183 {
184 log.debug( "Deactivating schedule " + schedule.getName() + " for Build Process" );
185
186 unschedule( schedule, ContinuumBuildJob.BUILD_GROUP );
187 }
188
189 private void unactivatePurgeSchedule( Schedule schedule )
190 throws SchedulesActivationException
191 {
192 log.debug( "Deactivating schedule " + schedule.getName() + " for Purge Process" );
193
194 unschedule( schedule, ContinuumPurgeJob.PURGE_GROUP );
195 }
196
197 protected void schedule( Schedule schedule, Continuum continuum, Class jobClass, String group )
198 throws SchedulesActivationException
199 {
200 if ( StringUtils.isEmpty( schedule.getCronExpression() ) )
201 {
202 log.info( "Not scheduling " + schedule.getName() );
203 return;
204 }
205
206 JobDataMap dataMap = new JobDataMap();
207
208 dataMap.put( "continuum", continuum );
209
210 dataMap.put( AbstractJob.LOGGER, log );
211
212 dataMap.put( ContinuumSchedulerConstants.SCHEDULE, schedule );
213
214
215
216 JobDetail jobDetail = new JobDetail( schedule.getName(), group, jobClass );
217
218 jobDetail.setJobDataMap( dataMap );
219
220 jobDetail.setDescription( schedule.getDescription() );
221
222 CronTrigger trigger = new CronTrigger();
223
224 trigger.setName( schedule.getName() );
225
226 trigger.setGroup( group );
227
228 Date startTime = new Date( System.currentTimeMillis() + delay * 1000 );
229
230 trigger.setStartTime( startTime );
231
232 trigger.setNextFireTime( startTime );
233
234 try
235 {
236 trigger.setCronExpression( schedule.getCronExpression() );
237 }
238 catch ( ParseException e )
239 {
240 throw new SchedulesActivationException( "Error parsing cron expression.", e );
241 }
242
243 try
244 {
245 scheduler.scheduleJob( jobDetail, trigger );
246
247 log.info( trigger.getName() + ": next fire time ->" + trigger.getNextFireTime() );
248 }
249 catch ( SchedulerException e )
250 {
251 throw new SchedulesActivationException( "Cannot schedule job ->" + jobClass.getName(), e );
252 }
253 }
254
255 private void unschedule( Schedule schedule, String group )
256 throws SchedulesActivationException
257 {
258 try
259 {
260 if ( schedule.isActive() )
261 {
262 log.info( "Stopping active schedule \"" + schedule.getName() + "\"." );
263
264 scheduler.interruptSchedule( schedule.getName(), group );
265 }
266
267 scheduler.unscheduleJob( schedule.getName(), group );
268 }
269 catch ( SchedulerException e )
270 {
271 throw new SchedulesActivationException( "Cannot unschedule build job \"" + schedule.getName() + "\".", e );
272 }
273 }
274
275 private boolean isScheduleFromBuildJob( Schedule schedule )
276 {
277 List<BuildDefinition> buildDef = buildDefinitionDao.getBuildDefinitionsBySchedule( schedule.getId() );
278
279
280
281 return buildDef.size() > 0;
282
283 }
284
285 private boolean isScheduleFromPurgeJob( Schedule schedule )
286 {
287 List<RepositoryPurgeConfiguration> repoPurgeConfigs =
288 repositoryPurgeConfigurationDao.getEnableRepositoryPurgeConfigurationsBySchedule( schedule.getId() );
289 List<DirectoryPurgeConfiguration> dirPurgeConfigs =
290 directoryPurgeConfigurationDao.getEnableDirectoryPurgeConfigurationsBySchedule( schedule.getId() );
291
292 return repoPurgeConfigs.size() > 0 || dirPurgeConfigs.size() > 0;
293
294 }
295 }