View Javadoc

1   package org.apache.continuum.taskqueue;
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.commons.lang.ArrayUtils;
23  import org.apache.continuum.dao.BuildDefinitionDao;
24  import org.apache.continuum.taskqueueexecutor.ParallelBuildsThreadedTaskQueueExecutor;
25  import org.apache.continuum.utils.build.BuildTrigger;
26  import org.apache.maven.continuum.model.project.BuildDefinition;
27  import org.apache.maven.continuum.store.ContinuumStoreException;
28  import org.codehaus.plexus.taskqueue.Task;
29  import org.codehaus.plexus.taskqueue.TaskQueue;
30  import org.codehaus.plexus.taskqueue.TaskQueueException;
31  import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
32  import org.codehaus.plexus.util.StringUtils;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  import java.util.ArrayList;
37  import java.util.List;
38  import java.util.Map;
39  import java.util.Set;
40  import javax.annotation.Resource;
41  
42  /**
43   * "Overall" build queue which has a checkout queue and a build queue.
44   *
45   * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
46   * @version $Id$
47   */
48  public class DefaultOverallBuildQueue
49      implements OverallBuildQueue
50  {
51      private static final Logger log = LoggerFactory.getLogger( DefaultOverallBuildQueue.class );
52  
53      @Resource
54      private BuildDefinitionDao buildDefinitionDao;
55  
56      private TaskQueueExecutor buildTaskQueueExecutor;
57  
58      private TaskQueueExecutor checkoutTaskQueueExecutor;
59  
60      private TaskQueueExecutor prepareBuildTaskQueueExecutor;
61  
62      private int id;
63  
64      private String name;
65  
66      public int getId()
67      {
68          return id;
69      }
70  
71      public void setId( int id )
72      {
73          this.id = id;
74      }
75  
76      public String getName()
77      {
78          return name;
79      }
80  
81      public void setName( String name )
82      {
83          this.name = name;
84      }
85  
86      /**
87       * @see OverallBuildQueue#addToCheckoutQueue(CheckOutTask)
88       */
89      public void addToCheckoutQueue( CheckOutTask checkoutTask )
90          throws TaskQueueException
91      {
92          getCheckoutQueue().put( checkoutTask );
93      }
94  
95      /**
96       * @see OverallBuildQueue#addToCheckoutQueue(List)
97       */
98      public void addToCheckoutQueue( List<CheckOutTask> checkoutTasks )
99          throws TaskQueueException
100     {
101         for ( CheckOutTask checkoutTask : checkoutTasks )
102         {
103             getCheckoutQueue().put( checkoutTask );
104         }
105     }
106 
107     /**
108      * @see OverallBuildQueue#getProjectsInCheckoutQueue()
109      */
110     public List<CheckOutTask> getProjectsInCheckoutQueue()
111         throws TaskQueueException
112     {
113         return getCheckoutQueue().getQueueSnapshot();
114     }
115 
116     /**
117      * @see OverallBuildQueue#isInCheckoutQueue(int)
118      */
119     public boolean isInCheckoutQueue( int projectId )
120         throws TaskQueueException
121     {
122         List<CheckOutTask> queue = getProjectsInCheckoutQueue();
123 
124         for ( CheckOutTask task : queue )
125         {
126             if ( task != null && task.getProjectId() == projectId )
127             {
128                 return true;
129             }
130         }
131         return false;
132     }
133 
134     /**
135      * @see OverallBuildQueue#removeProjectFromCheckoutQueue(int)
136      */
137     public boolean removeProjectFromCheckoutQueue( int projectId )
138         throws TaskQueueException
139     {
140         List<CheckOutTask> queue = getProjectsInCheckoutQueue();
141 
142         for ( CheckOutTask task : queue )
143         {
144             if ( task != null && task.getProjectId() == projectId )
145             {
146                 return getCheckoutQueue().remove( task );
147             }
148         }
149         return false;
150     }
151 
152     /**
153      * @see OverallBuildQueue#removeProjectsFromCheckoutQueue(int[])
154      */
155     public boolean removeProjectsFromCheckoutQueue( int[] projectsId )
156         throws TaskQueueException
157     {
158         if ( projectsId == null )
159         {
160             return false;
161         }
162         if ( projectsId.length < 1 )
163         {
164             return false;
165         }
166         List<CheckOutTask> queue = getProjectsInCheckoutQueue();
167 
168         List<CheckOutTask> tasks = new ArrayList<CheckOutTask>();
169 
170         for ( CheckOutTask task : queue )
171         {
172             if ( task != null )
173             {
174                 if ( ArrayUtils.contains( projectsId, task.getProjectId() ) )
175                 {
176                     tasks.add( task );
177                 }
178             }
179         }
180         return !tasks.isEmpty() && getCheckoutQueue().removeAll( tasks );
181     }
182 
183     /**
184      * @see OverallBuildQueue#removeTasksFromCheckoutQueueWithHashCodes(int[])
185      */
186     public void removeTasksFromCheckoutQueueWithHashCodes( int[] hashCodes )
187         throws TaskQueueException
188     {
189         List<CheckOutTask> queue = getProjectsInCheckoutQueue();
190 
191         for ( CheckOutTask task : queue )
192         {
193             if ( ArrayUtils.contains( hashCodes, task.hashCode() ) )
194             {
195                 getCheckoutQueue().remove( task );
196             }
197         }
198     }
199 
200     /**
201      * @see OverallBuildQueue#addToBuildQueue(BuildProjectTask)
202      */
203     public void addToBuildQueue( BuildProjectTask buildTask )
204         throws TaskQueueException
205     {
206         getBuildQueue().put( buildTask );
207     }
208 
209     /**
210      * @see OverallBuildQueue#addToBuildQueue(List)
211      */
212     public void addToBuildQueue( List<BuildProjectTask> buildTasks )
213         throws TaskQueueException
214     {
215         for ( BuildProjectTask buildTask : buildTasks )
216         {
217             getBuildQueue().put( buildTask );
218         }
219     }
220 
221     /**
222      * @see OverallBuildQueue#getProjectsInBuildQueue()
223      */
224     public List<BuildProjectTask> getProjectsInBuildQueue()
225         throws TaskQueueException
226     {
227         return getBuildQueue().getQueueSnapshot();
228     }
229 
230     /**
231      * @see OverallBuildQueue#isInBuildQueue(int)
232      */
233     public boolean isInBuildQueue( int projectId )
234         throws TaskQueueException
235     {
236         return isInBuildQueue( projectId, -1 );
237     }
238 
239     /**
240      * @see OverallBuildQueue#isInBuildQueue(int, int)
241      */
242     public boolean isInBuildQueue( int projectId, int buildDefinitionId )
243         throws TaskQueueException
244     {
245         List<BuildProjectTask> queue = getProjectsInBuildQueue();
246         for ( BuildProjectTask buildTask : queue )
247         {
248             if ( buildTask != null )
249             {
250                 if ( buildDefinitionId < 0 )
251                 {
252                     if ( buildTask.getProjectId() == projectId )
253                     {
254                         return true;
255                     }
256                 }
257                 else
258                 {
259                     if ( buildTask.getProjectId() == projectId &&
260                         buildTask.getBuildDefinitionId() == buildDefinitionId )
261                     {
262                         return true;
263                     }
264                 }
265             }
266         }
267         return false;
268     }
269 
270     /**
271      * @see OverallBuildQueue#cancelBuildTask(int)
272      */
273     public void cancelBuildTask( int projectId )
274     {
275         BuildProjectTask task = (BuildProjectTask) buildTaskQueueExecutor.getCurrentTask();
276         if ( task != null && task.getProjectId() == projectId )
277         {
278             log.info(
279                 "Cancelling build task for project '" + projectId + "' in task executor '" + buildTaskQueueExecutor );
280             buildTaskQueueExecutor.cancelTask( task );
281         }
282     }
283 
284     /**
285      * @see OverallBuildQueue#cancelCheckoutTask(int)
286      */
287     public void cancelCheckoutTask( int projectId )
288         throws TaskQueueException
289     {
290         CheckOutTask task = (CheckOutTask) checkoutTaskQueueExecutor.getCurrentTask();
291         if ( task != null && task.getProjectId() == projectId )
292         {
293             log.info( "Cancelling checkout task for project '" + projectId + "' in task executor '" +
294                           checkoutTaskQueueExecutor );
295             checkoutTaskQueueExecutor.cancelTask( task );
296         }
297     }
298 
299     /**
300      * @see OverallBuildQueue#cancelCurrentBuild()
301      */
302     public boolean cancelCurrentBuild()
303     {
304         Task task = buildTaskQueueExecutor.getCurrentTask();
305         if ( task != null )
306         {
307             return buildTaskQueueExecutor.cancelTask( task );
308         }
309 
310         log.info( "No build task currently executing on build executor: " + buildTaskQueueExecutor );
311         return false;
312     }
313 
314     /**
315      * @see OverallBuildQueue#cancelCurrentCheckout()
316      */
317     public boolean cancelCurrentCheckout()
318     {
319         Task task = checkoutTaskQueueExecutor.getCurrentTask();
320         if ( task != null )
321         {
322             return checkoutTaskQueueExecutor.cancelTask( task );
323         }
324 
325         log.info( "No checkout task currently executing on checkout task executor: " + checkoutTaskQueueExecutor );
326         return false;
327     }
328 
329     /**
330      * @see OverallBuildQueue#removeProjectFromBuildQueue(int, int, BuildTrigger, String, int)
331      */
332     public boolean removeProjectFromBuildQueue( int projectId, int buildDefinitionId, BuildTrigger buildTrigger,
333                                                 String projectName, int projectGroupId )
334         throws TaskQueueException
335     {
336         BuildDefinition buildDefinition;
337 
338         // maybe we could just pass the label as a parameter to eliminate dependency to BuildDefinitionDAO?
339         try
340         {
341             buildDefinition = buildDefinitionDao.getBuildDefinition( buildDefinitionId );
342         }
343         catch ( ContinuumStoreException e )
344         {
345             throw new TaskQueueException( "Error while removing project from build queue: " + projectName, e );
346         }
347 
348         String buildDefinitionLabel = buildDefinition.getDescription();
349         if ( StringUtils.isEmpty( buildDefinitionLabel ) )
350         {
351             buildDefinitionLabel = buildDefinition.getGoals();
352         }
353 
354         BuildProjectTask buildProjectTask = new BuildProjectTask( projectId, buildDefinitionId, buildTrigger,
355                                                                   projectName, buildDefinitionLabel, null,
356                                                                   projectGroupId );
357 
358         return getBuildQueue().remove( buildProjectTask );
359     }
360 
361     /**
362      * @see OverallBuildQueue#removeProjectsFromBuildQueue(int[])
363      */
364     public boolean removeProjectsFromBuildQueue( int[] projectIds )
365         throws TaskQueueException
366     {
367         if ( projectIds == null )
368         {
369             return false;
370         }
371         if ( projectIds.length < 1 )
372         {
373             return false;
374         }
375         List<BuildProjectTask> queue = getProjectsInBuildQueue();
376 
377         List<BuildProjectTask> tasks = new ArrayList<BuildProjectTask>();
378 
379         for ( BuildProjectTask buildTask : queue )
380         {
381             if ( buildTask != null )
382             {
383                 if ( ArrayUtils.contains( projectIds, buildTask.getProjectId() ) )
384                 {
385                     tasks.add( buildTask );
386                 }
387             }
388         }
389 
390         for ( BuildProjectTask buildProjectTask : tasks )
391         {
392             log.info( "cancel build for project " + buildProjectTask.getProjectId() );
393         }
394 
395         return !tasks.isEmpty() && getBuildQueue().removeAll( tasks );
396     }
397 
398     /**
399      * @see OverallBuildQueue#removeProjectFromBuildQueue(int)
400      */
401     public boolean removeProjectFromBuildQueue( int projectId )
402         throws TaskQueueException
403     {
404         List<BuildProjectTask> queue = getProjectsInBuildQueue();
405 
406         for ( BuildProjectTask buildTask : queue )
407         {
408             if ( buildTask != null && buildTask.getProjectId() == projectId )
409             {
410                 return getBuildQueue().remove( buildTask );
411             }
412         }
413         return false;
414     }
415 
416     /**
417      * @see OverallBuildQueue#removeProjectsFromBuildQueueWithHashCodes(int[])
418      */
419     public void removeProjectsFromBuildQueueWithHashCodes( int[] hashCodes )
420         throws TaskQueueException
421     {
422         List<BuildProjectTask> queue = getProjectsInBuildQueue();
423         for ( BuildProjectTask task : queue )
424         {
425             if ( ArrayUtils.contains( hashCodes, task.hashCode() ) )
426             {
427                 getBuildQueue().remove( task );
428             }
429         }
430     }
431 
432     /* Prepare Build */
433 
434     /**
435      * @see OverallBuildQueue#addToPrepareBuildQueue(PrepareBuildProjectsTask)
436      */
437     public void addToPrepareBuildQueue( PrepareBuildProjectsTask prepareBuildTask )
438         throws TaskQueueException
439     {
440         getPrepareBuildQueue().put( prepareBuildTask );
441     }
442 
443     /**
444      * @see OverallBuildQueue#addToPrepareBuildQueue(List)
445      */
446     public void addToPrepareBuildQueue( List<PrepareBuildProjectsTask> prepareBuildTasks )
447         throws TaskQueueException
448     {
449         for ( PrepareBuildProjectsTask prepareBuildTask : prepareBuildTasks )
450         {
451             getPrepareBuildQueue().put( prepareBuildTask );
452         }
453     }
454 
455     /**
456      * @see OverallBuildQueue#getProjectsInPrepareBuildQueue()
457      */
458     public List<PrepareBuildProjectsTask> getProjectsInPrepareBuildQueue()
459         throws TaskQueueException
460     {
461         return getPrepareBuildQueue().getQueueSnapshot();
462     }
463 
464     /**
465      * @see OverallBuildQueue#isInPrepareBuildQueue(int)
466      */
467     public boolean isInPrepareBuildQueue( int projectId )
468         throws TaskQueueException
469     {
470         List<PrepareBuildProjectsTask> queue = getProjectsInPrepareBuildQueue();
471         for ( PrepareBuildProjectsTask task : queue )
472         {
473             if ( task != null )
474             {
475                 Map<Integer, Integer> map = task.getProjectsBuildDefinitionsMap();
476 
477                 if ( map.size() > 0 )
478                 {
479                     Set<Integer> projectIds = map.keySet();
480 
481                     if ( projectIds.contains( new Integer( projectId ) ) )
482                     {
483                         log.info( "Project {} is already in prepare build queue", projectId );
484                         return true;
485                     }
486                 }
487             }
488         }
489 
490         return false;
491     }
492 
493     /**
494      * @see OverallBuildQueue#isInPrepareBuildQueue(int, int)
495      */
496     public boolean isInPrepareBuildQueue( int projectGroupId, int scmRootId )
497         throws TaskQueueException
498     {
499         List<PrepareBuildProjectsTask> queue = getProjectsInPrepareBuildQueue();
500         for ( PrepareBuildProjectsTask task : queue )
501         {
502             if ( task != null && task.getProjectGroupId() == projectGroupId && task.getProjectScmRootId() == scmRootId )
503             {
504                 log.info( "Project group {} with scm root {} is in prepare build queue {}",
505                           new Object[]{projectGroupId, scmRootId, task} );
506                 return true;
507             }
508         }
509 
510         return false;
511     }
512 
513     /**
514      * @see OverallBuildQueue#isInPrepareBuildQueue(int, String)
515      */
516     public boolean isInPrepareBuildQueue( int projectGroupId, String scmRootAddress )
517         throws TaskQueueException
518     {
519         List<PrepareBuildProjectsTask> queue = getProjectsInPrepareBuildQueue();
520         for ( PrepareBuildProjectsTask task : queue )
521         {
522             if ( task != null && task.getProjectGroupId() == projectGroupId && task.getScmRootAddress().equals(
523                 scmRootAddress ) )
524             {
525                 log.info( "Project group {} with scm root {} is in prepare build queue {}",
526                           new Object[]{projectGroupId, scmRootAddress, task} );
527                 return true;
528             }
529         }
530 
531         return false;
532     }
533 
534     /**
535      * @see OverallBuildQueue#cancelPrepareBuildTask(int, int)
536      */
537     public void cancelPrepareBuildTask( int projectGroupId, int scmRootId )
538     {
539         PrepareBuildProjectsTask task = (PrepareBuildProjectsTask) prepareBuildTaskQueueExecutor.getCurrentTask();
540         if ( task != null && task.getProjectGroupId() == projectGroupId && task.getProjectScmRootId() == scmRootId )
541         {
542             log.info( "Cancelling prepare build task for project group '{}' with scmRootId '{}' in task executor '{}'",
543                       new Object[]{projectGroupId, scmRootId, prepareBuildTaskQueueExecutor} );
544             prepareBuildTaskQueueExecutor.cancelTask( task );
545         }
546     }
547 
548     /**
549      * @see OverallBuildQueue#cancelPrepareBuildTask(int)
550      */
551     public void cancelPrepareBuildTask( int projectId )
552     {
553         PrepareBuildProjectsTask task = (PrepareBuildProjectsTask) prepareBuildTaskQueueExecutor.getCurrentTask();
554         if ( task != null )
555         {
556             Map<Integer, Integer> map = task.getProjectsBuildDefinitionsMap();
557 
558             if ( map.size() > 0 )
559             {
560                 Set<Integer> projectIds = map.keySet();
561 
562                 if ( projectIds.contains( new Integer( projectId ) ) )
563                 {
564                     log.info( "Cancelling prepare build task for project '{}' in task executor '{}'", projectId,
565                               prepareBuildTaskQueueExecutor );
566                     prepareBuildTaskQueueExecutor.cancelTask( task );
567                 }
568             }
569         }
570     }
571 
572     /**
573      * @see OverallBuildQueue#cancelCurrentPrepareBuild()
574      */
575     public boolean cancelCurrentPrepareBuild()
576     {
577         Task task = prepareBuildTaskQueueExecutor.getCurrentTask();
578         if ( task != null )
579         {
580             return prepareBuildTaskQueueExecutor.cancelTask( task );
581         }
582 
583         log.info( "No prepare build task currently executing on build executor: {}", buildTaskQueueExecutor );
584         return false;
585     }
586 
587     /**
588      * @see OverallBuildQueue#removeProjectFromPrepareBuildQueue(int, int)
589      */
590     public boolean removeProjectFromPrepareBuildQueue( int projectGroupId, int scmRootId )
591         throws TaskQueueException
592     {
593         List<PrepareBuildProjectsTask> tasks = getProjectsInPrepareBuildQueue();
594 
595         if ( tasks != null )
596         {
597             for ( PrepareBuildProjectsTask task : tasks )
598             {
599                 if ( task.getProjectGroupId() == projectGroupId && task.getProjectScmRootId() == scmRootId )
600                 {
601                     return getPrepareBuildQueue().remove( task );
602                 }
603             }
604         }
605 
606         return false;
607     }
608 
609     /**
610      * @see OverallBuildQueue#removeProjectFromPrepareBuildQueue(int, String)
611      */
612     public boolean removeProjectFromPrepareBuildQueue( int projectGroupId, String scmRootAddress )
613         throws TaskQueueException
614     {
615         List<PrepareBuildProjectsTask> queue = getProjectsInPrepareBuildQueue();
616 
617         for ( PrepareBuildProjectsTask task : queue )
618         {
619             if ( task != null && task.getProjectGroupId() == projectGroupId &&
620                 task.getScmRootAddress().equals( scmRootAddress ) )
621             {
622                 return getPrepareBuildQueue().remove( task );
623             }
624         }
625 
626         return false;
627     }
628 
629     /**
630      * @see OverallBuildQueue#removeProjectsFromPrepareBuildQueueWithHashCodes(int[])
631      */
632     public void removeProjectsFromPrepareBuildQueueWithHashCodes( int[] hashCodes )
633         throws TaskQueueException
634     {
635         List<PrepareBuildProjectsTask> tasks = getProjectsInPrepareBuildQueue();
636 
637         if ( tasks != null )
638         {
639             for ( PrepareBuildProjectsTask task : tasks )
640             {
641                 if ( ArrayUtils.contains( hashCodes, task.getHashCode() ) )
642                 {
643                     getPrepareBuildQueue().remove( task );
644                 }
645             }
646         }
647     }
648 
649     /**
650      * @see OverallBuildQueue#getCheckoutQueue()
651      */
652     public TaskQueue getCheckoutQueue()
653     {
654         return ( (ParallelBuildsThreadedTaskQueueExecutor) checkoutTaskQueueExecutor ).getQueue();
655     }
656 
657     /**
658      * @see OverallBuildQueue#getBuildQueue()
659      */
660     public TaskQueue getBuildQueue()
661     {
662         return ( (ParallelBuildsThreadedTaskQueueExecutor) buildTaskQueueExecutor ).getQueue();
663     }
664 
665     /**
666      * @see OverallBuildQueue#getPrepareBuildQueue()
667      */
668     public TaskQueue getPrepareBuildQueue()
669     {
670         return ( (ParallelBuildsThreadedTaskQueueExecutor) prepareBuildTaskQueueExecutor ).getQueue();
671     }
672 
673     /**
674      * @see OverallBuildQueue#getBuildTaskQueueExecutor()
675      */
676     public TaskQueueExecutor getBuildTaskQueueExecutor()
677     {
678         return buildTaskQueueExecutor;
679     }
680 
681     /**
682      * @see OverallBuildQueue#getCheckoutTaskQueueExecutor()
683      */
684     public TaskQueueExecutor getCheckoutTaskQueueExecutor()
685     {
686         return checkoutTaskQueueExecutor;
687     }
688 
689     /**
690      * @see OverallBuildQueue#getPrepareBuildTaskQueueExecutor()
691      */
692     public TaskQueueExecutor getPrepareBuildTaskQueueExecutor()
693     {
694         return prepareBuildTaskQueueExecutor;
695     }
696 
697     public void setBuildDefinitionDao( BuildDefinitionDao buildDefinitionDao )
698     {
699         this.buildDefinitionDao = buildDefinitionDao;
700     }
701 
702     public void setBuildTaskQueueExecutor( TaskQueueExecutor buildTaskQueueExecutor )
703     {
704         this.buildTaskQueueExecutor = buildTaskQueueExecutor;
705     }
706 
707     public void setCheckoutTaskQueueExecutor( TaskQueueExecutor checkoutTaskQueueExecutor )
708     {
709         this.checkoutTaskQueueExecutor = checkoutTaskQueueExecutor;
710     }
711 
712     public void setPrepareBuildTaskQueueExecutor( TaskQueueExecutor prepareBuildTaskQueueExecutor )
713     {
714         this.prepareBuildTaskQueueExecutor = prepareBuildTaskQueueExecutor;
715     }
716 }