1 | package org.apache.maven.continuum.build.settings; |
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 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 | * @author <a href="mailto:jason@maven.org">Jason van Zyl</a> |
52 | * @version $Id: DefaultSchedulesActivator.java 780708 2009-06-01 16:29:31Z jmorales $ |
53 | * @plexus.component role="org.apache.maven.continuum.build.settings.SchedulesActivator" |
54 | */ |
55 | public class DefaultSchedulesActivator |
56 | implements SchedulesActivator |
57 | { |
58 | private static final Logger log = LoggerFactory.getLogger( DefaultSchedulesActivator.class ); |
59 | |
60 | /** |
61 | * @plexus.requirement |
62 | */ |
63 | private DirectoryPurgeConfigurationDao directoryPurgeConfigurationDao; |
64 | |
65 | /** |
66 | * @plexus.requirement |
67 | */ |
68 | private RepositoryPurgeConfigurationDao repositoryPurgeConfigurationDao; |
69 | |
70 | /** |
71 | * @plexus.requirement |
72 | */ |
73 | private BuildDefinitionDao buildDefinitionDao; |
74 | |
75 | /** |
76 | * @plexus.requirement |
77 | */ |
78 | private ScheduleDao scheduleDao; |
79 | |
80 | /** |
81 | * @plexus.requirement role-hint="default" |
82 | */ |
83 | private Scheduler scheduler; |
84 | |
85 | // private int delay = 3600; |
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 | // the name + group makes the job unique |
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 | // Take account templateBuildDefinition too. |
279 | // A improvement will be add schedule only for active buildDefinition, but it would need activate |
280 | // schedule job in add project and add group process |
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 | } |