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 java.util.ArrayList; |
23 | import java.util.List; |
24 | import java.util.Map; |
25 | import java.util.Set; |
26 | |
27 | import org.apache.commons.lang.ArrayUtils; |
28 | import org.apache.continuum.buildmanager.BuildManagerException; |
29 | import org.apache.continuum.buildmanager.BuildsManager; |
30 | import org.apache.continuum.dao.ProjectDao; |
31 | import org.apache.continuum.model.repository.LocalRepository; |
32 | import org.apache.continuum.model.repository.RepositoryPurgeConfiguration; |
33 | import org.apache.continuum.purge.PurgeConfigurationService; |
34 | import org.apache.continuum.purge.task.PurgeTask; |
35 | import org.apache.continuum.taskqueue.BuildProjectTask; |
36 | import org.apache.continuum.taskqueue.PrepareBuildProjectsTask; |
37 | import org.apache.maven.continuum.model.project.Project; |
38 | import org.apache.maven.continuum.release.tasks.PerformReleaseProjectTask; |
39 | import org.apache.maven.continuum.release.tasks.PrepareReleaseProjectTask; |
40 | import org.apache.maven.continuum.store.ContinuumStoreException; |
41 | import org.codehaus.plexus.PlexusConstants; |
42 | import org.codehaus.plexus.PlexusContainer; |
43 | import org.codehaus.plexus.component.repository.exception.ComponentLookupException; |
44 | import org.codehaus.plexus.context.Context; |
45 | import org.codehaus.plexus.context.ContextException; |
46 | import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; |
47 | import org.codehaus.plexus.taskqueue.Task; |
48 | import org.codehaus.plexus.taskqueue.TaskQueue; |
49 | import org.codehaus.plexus.taskqueue.TaskQueueException; |
50 | import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor; |
51 | import org.slf4j.Logger; |
52 | import org.slf4j.LoggerFactory; |
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 && |
135 | task.getScmRootAddress().equals( 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 | } |