View Javadoc

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 }