View Javadoc

1   package org.apache.continuum.taskqueue.manager;
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.buildmanager.BuildManagerException;
24  import org.apache.continuum.buildmanager.BuildsManager;
25  import org.apache.continuum.dao.ProjectDao;
26  import org.apache.continuum.model.repository.LocalRepository;
27  import org.apache.continuum.model.repository.RepositoryPurgeConfiguration;
28  import org.apache.continuum.purge.PurgeConfigurationService;
29  import org.apache.continuum.purge.task.PurgeTask;
30  import org.apache.continuum.taskqueue.BuildProjectTask;
31  import org.apache.continuum.taskqueue.PrepareBuildProjectsTask;
32  import org.apache.maven.continuum.model.project.Project;
33  import org.apache.maven.continuum.release.tasks.PerformReleaseProjectTask;
34  import org.apache.maven.continuum.release.tasks.PrepareReleaseProjectTask;
35  import org.apache.maven.continuum.store.ContinuumStoreException;
36  import org.codehaus.plexus.PlexusConstants;
37  import org.codehaus.plexus.PlexusContainer;
38  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
39  import org.codehaus.plexus.context.Context;
40  import org.codehaus.plexus.context.ContextException;
41  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
42  import org.codehaus.plexus.taskqueue.Task;
43  import org.codehaus.plexus.taskqueue.TaskQueue;
44  import org.codehaus.plexus.taskqueue.TaskQueueException;
45  import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
46  import org.slf4j.Logger;
47  import org.slf4j.LoggerFactory;
48  
49  import java.util.ArrayList;
50  import java.util.List;
51  import java.util.Map;
52  import java.util.Set;
53  
54  /**
55   * @author <a href="mailto:ctan@apache.org">Maria Catherine Tan</a>
56   * @plexus.component role="org.apache.continuum.taskqueue.manager.TaskQueueManager" role-hint="default"
57   */
58  public class DefaultTaskQueueManager
59      implements TaskQueueManager, Contextualizable
60  {
61      private static final Logger log = LoggerFactory.getLogger( DefaultTaskQueueManager.class );
62  
63      /**
64       * @plexus.requirement role-hint="distributed-build-project"
65       */
66      private TaskQueue distributedBuildQueue;
67  
68      /**
69       * @plexus.requirement role-hint="purge"
70       */
71      private TaskQueue purgeQueue;
72  
73      /**
74       * @plexus.requirement role-hint="prepare-release"
75       */
76      private TaskQueue prepareReleaseQueue;
77  
78      /**
79       * @plexus.requirement role-hint="perform-release"
80       */
81      private TaskQueue performReleaseQueue;
82  
83      /**
84       * @plexus.requirement
85       */
86      private ProjectDao projectDao;
87  
88      /**
89       * @plexus.requirement
90       */
91      private PurgeConfigurationService purgeConfigurationService;
92  
93      /**
94       * @plexus.requirement role-hint="parallel"
95       */
96      private BuildsManager buildsManager;
97  
98      private PlexusContainer container;
99  
100     public TaskQueue getDistributedBuildQueue()
101     {
102         return distributedBuildQueue;
103     }
104 
105     public List<PrepareBuildProjectsTask> getDistributedBuildProjectsInQueue()
106         throws TaskQueueManagerException
107     {
108         try
109         {
110             return distributedBuildQueue.getQueueSnapshot();
111         }
112         catch ( TaskQueueException e )
113         {
114             throw new TaskQueueManagerException( "Error while getting the distributed building queue", e );
115         }
116     }
117 
118     public TaskQueue getPurgeQueue()
119     {
120         return purgeQueue;
121     }
122 
123     public boolean isInDistributedBuildQueue( int projectGroupId, String scmRootAddress )
124         throws TaskQueueManagerException
125     {
126         try
127         {
128             List<PrepareBuildProjectsTask> queue = distributedBuildQueue.getQueueSnapshot();
129 
130             for ( PrepareBuildProjectsTask task : queue )
131             {
132                 if ( task != null )
133                 {
134                     if ( task.getProjectGroupId() == projectGroupId && task.getScmRootAddress().equals(
135                         scmRootAddress ) )
136                     {
137                         return true;
138                     }
139                 }
140             }
141 
142             return false;
143         }
144         catch ( TaskQueueException e )
145         {
146             throw new TaskQueueManagerException( "Error while getting the tasks in distributed build queue", e );
147         }
148     }
149 
150     public boolean isInPurgeQueue( int purgeConfigId )
151         throws TaskQueueManagerException
152     {
153         List<PurgeTask> queue = getAllPurgeConfigurationsInPurgeQueue();
154 
155         for ( PurgeTask task : queue )
156         {
157             if ( task != null && task.getPurgeConfigurationId() == purgeConfigId )
158             {
159                 return true;
160             }
161         }
162         return false;
163     }
164 
165     public boolean isRepositoryInPurgeQueue( int repositoryId )
166         throws TaskQueueManagerException
167     {
168         List<RepositoryPurgeConfiguration> repoPurgeConfigs =
169             purgeConfigurationService.getRepositoryPurgeConfigurationsByRepository( repositoryId );
170 
171         for ( RepositoryPurgeConfiguration repoPurge : repoPurgeConfigs )
172         {
173             if ( isInPurgeQueue( repoPurge.getId() ) )
174             {
175                 return true;
176             }
177         }
178         return false;
179     }
180 
181     public boolean isRepositoryInUse( int repositoryId )
182         throws TaskQueueManagerException
183     {
184         try
185         {
186             Map<String, BuildProjectTask> currentBuilds = buildsManager.getCurrentBuilds();
187             Set<String> keys = currentBuilds.keySet();
188 
189             for ( String key : keys )
190             {
191                 BuildProjectTask task = currentBuilds.get( key );
192                 if ( task != null )
193                 {
194                     int projectId = task.getProjectId();
195 
196                     Project project = projectDao.getProject( projectId );
197                     LocalRepository repository = project.getProjectGroup().getLocalRepository();
198 
199                     if ( repository != null && repository.getId() == repositoryId )
200                     {
201                         return true;
202                     }
203                 }
204             }
205 
206             return false;
207         }
208         catch ( BuildManagerException e )
209         {
210             log.error( "Error occured while getting current builds: " + e.getMessage() );
211             throw new TaskQueueManagerException( e.getMessage(), e );
212         }
213         catch ( ContinuumStoreException e )
214         {
215             log.error( "Error occured while getting project details: " + e.getMessage() );
216             throw new TaskQueueManagerException( e.getMessage(), e );
217         }
218     }
219 
220     public boolean isProjectInReleaseStage( String releaseId )
221         throws TaskQueueManagerException
222     {
223         Task prepareTask = getCurrentTask( "prepare-release" );
224         if ( prepareTask != null && prepareTask instanceof PrepareReleaseProjectTask )
225         {
226             if ( ( (PrepareReleaseProjectTask) prepareTask ).getReleaseId().equals( releaseId ) )
227             {
228                 return true;
229             }
230             else
231             {
232                 try
233                 {
234                     // check if in queue
235                     List<Task> tasks = prepareReleaseQueue.getQueueSnapshot();
236                     for ( Task prepareReleaseTask : tasks )
237                     {
238                         if ( ( (PrepareReleaseProjectTask) prepareReleaseTask ).getReleaseId().equals( releaseId ) )
239                         {
240                             return true;
241                         }
242                     }
243                 }
244                 catch ( TaskQueueException e )
245                 {
246                     throw new TaskQueueManagerException( e );
247                 }
248             }
249         }
250 
251         Task performTask = getCurrentTask( "perform-release" );
252         if ( performTask != null && performTask instanceof PerformReleaseProjectTask )
253         {
254             if ( ( (PerformReleaseProjectTask) performTask ).getReleaseId().equals( releaseId ) )
255             {
256                 return true;
257             }
258             else
259             {
260                 try
261                 {
262                     // check if in queue
263                     List<Task> tasks = performReleaseQueue.getQueueSnapshot();
264                     for ( Task performReleaseTask : tasks )
265                     {
266                         if ( ( (PerformReleaseProjectTask) performReleaseTask ).getReleaseId().equals( releaseId ) )
267                         {
268                             return true;
269                         }
270                     }
271                 }
272                 catch ( TaskQueueException e )
273                 {
274                     throw new TaskQueueManagerException( e );
275                 }
276             }
277         }
278 
279         return false;
280     }
281 
282     public boolean releaseInProgress()
283         throws TaskQueueManagerException
284     {
285         Task task = getCurrentTask( "perform-release" );
286 
287         return task != null && task instanceof PerformReleaseProjectTask;
288     }
289 
290     public void removeFromDistributedBuildQueue( int projectGroupId, String scmRootAddress )
291         throws TaskQueueManagerException
292     {
293         List<PrepareBuildProjectsTask> queue = getDistributedBuildProjectsInQueue();
294 
295         for ( PrepareBuildProjectsTask task : queue )
296         {
297             if ( task.getProjectGroupId() == projectGroupId && task.getScmRootAddress().equals( scmRootAddress ) )
298             {
299                 distributedBuildQueue.remove( task );
300             }
301         }
302     }
303 
304     public boolean removeFromPurgeQueue( int purgeConfigId )
305         throws TaskQueueManagerException
306     {
307         List<PurgeTask> queue = getAllPurgeConfigurationsInPurgeQueue();
308 
309         for ( PurgeTask task : queue )
310         {
311             if ( task != null && task.getPurgeConfigurationId() == purgeConfigId )
312             {
313                 return purgeQueue.remove( task );
314             }
315         }
316         return false;
317     }
318 
319     public boolean removeFromPurgeQueue( int[] purgeConfigIds )
320         throws TaskQueueManagerException
321     {
322         if ( purgeConfigIds == null )
323         {
324             return false;
325         }
326 
327         if ( purgeConfigIds.length < 1 )
328         {
329             return false;
330         }
331 
332         List<PurgeTask> queue = getAllPurgeConfigurationsInPurgeQueue();
333 
334         List<PurgeTask> tasks = new ArrayList<PurgeTask>();
335 
336         for ( PurgeTask task : queue )
337         {
338             if ( task != null )
339             {
340                 if ( ArrayUtils.contains( purgeConfigIds, task.getPurgeConfigurationId() ) )
341                 {
342                     tasks.add( task );
343                 }
344             }
345         }
346 
347         return !tasks.isEmpty() && purgeQueue.removeAll( tasks );
348     }
349 
350     public void removeRepositoryFromPurgeQueue( int repositoryId )
351         throws TaskQueueManagerException
352     {
353         List<RepositoryPurgeConfiguration> repoPurgeConfigs =
354             purgeConfigurationService.getRepositoryPurgeConfigurationsByRepository( repositoryId );
355 
356         for ( RepositoryPurgeConfiguration repoPurge : repoPurgeConfigs )
357         {
358             removeFromPurgeQueue( repoPurge.getId() );
359         }
360     }
361 
362     public void removeTasksFromDistributedBuildQueueWithHashCodes( int[] hashCodes )
363         throws TaskQueueManagerException
364     {
365         List<PrepareBuildProjectsTask> queue = getDistributedBuildProjectsInQueue();
366 
367         for ( PrepareBuildProjectsTask task : queue )
368         {
369             if ( ArrayUtils.contains( hashCodes, task.hashCode() ) )
370             {
371                 distributedBuildQueue.remove( task );
372             }
373         }
374     }
375 
376     public void contextualize( Context context )
377         throws ContextException
378     {
379         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
380     }
381 
382     private List<PurgeTask> getAllPurgeConfigurationsInPurgeQueue()
383         throws TaskQueueManagerException
384     {
385         try
386         {
387             return purgeQueue.getQueueSnapshot();
388         }
389         catch ( TaskQueueException e )
390         {
391             throw new TaskQueueManagerException( "Error while getting the purge configs in purge queue", e );
392         }
393     }
394 
395     private Task getCurrentTask( String task )
396         throws TaskQueueManagerException
397     {
398         try
399         {
400             TaskQueueExecutor executor = (TaskQueueExecutor) container.lookup( TaskQueueExecutor.class, task );
401             return executor.getCurrentTask();
402         }
403         catch ( ComponentLookupException e )
404         {
405             throw new TaskQueueManagerException( "Unable to lookup current task", e );
406         }
407     }
408 }