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