1 package org.apache.continuum.buildagent;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.io.FileUtils;
23 import org.apache.commons.lang.ArrayUtils;
24 import org.apache.commons.lang.StringEscapeUtils;
25 import org.apache.continuum.buildagent.buildcontext.BuildContext;
26 import org.apache.continuum.buildagent.buildcontext.manager.BuildContextManager;
27 import org.apache.continuum.buildagent.configuration.BuildAgentConfigurationService;
28 import org.apache.continuum.buildagent.manager.BuildAgentManager;
29 import org.apache.continuum.buildagent.manager.BuildAgentPurgeManager;
30 import org.apache.continuum.buildagent.manager.BuildAgentReleaseManager;
31 import org.apache.continuum.buildagent.model.Installation;
32 import org.apache.continuum.buildagent.taskqueue.PrepareBuildProjectsTask;
33 import org.apache.continuum.buildagent.taskqueue.manager.BuildAgentTaskQueueManager;
34 import org.apache.continuum.buildagent.utils.ContinuumBuildAgentUtil;
35 import org.apache.continuum.buildagent.utils.WorkingCopyContentGenerator;
36 import org.apache.continuum.taskqueue.BuildProjectTask;
37 import org.apache.continuum.taskqueue.manager.TaskQueueManagerException;
38 import org.apache.continuum.utils.build.BuildTrigger;
39 import org.apache.continuum.utils.release.ReleaseUtil;
40 import org.apache.maven.continuum.ContinuumException;
41 import org.apache.maven.continuum.model.project.BuildResult;
42 import org.apache.maven.continuum.model.scm.ChangeFile;
43 import org.apache.maven.continuum.model.scm.ChangeSet;
44 import org.apache.maven.continuum.model.scm.ScmResult;
45 import org.apache.maven.continuum.project.ContinuumProjectState;
46 import org.apache.maven.continuum.release.ContinuumReleaseException;
47 import org.apache.maven.shared.release.ReleaseResult;
48 import org.codehaus.plexus.taskqueue.TaskQueueException;
49 import org.codehaus.plexus.util.StringUtils;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 import java.io.File;
54 import java.io.IOException;
55 import java.text.MessageFormat;
56 import java.util.ArrayList;
57 import java.util.HashMap;
58 import java.util.List;
59 import java.util.Map;
60 import java.util.Properties;
61 import java.util.regex.Matcher;
62 import java.util.regex.Pattern;
63 import javax.activation.MimetypesFileTypeMap;
64
65
66
67
68 public class ContinuumBuildAgentServiceImpl
69 implements ContinuumBuildAgentService
70 {
71 private static final Logger log = LoggerFactory.getLogger( ContinuumBuildAgentServiceImpl.class );
72
73 private static final String FILE_SEPARATOR = System.getProperty( "file.separator" );
74
75
76
77
78 private BuildAgentConfigurationService buildAgentConfigurationService;
79
80
81
82
83 private BuildAgentTaskQueueManager buildAgentTaskQueueManager;
84
85
86
87
88 private BuildContextManager buildContextManager;
89
90
91
92
93 private WorkingCopyContentGenerator generator;
94
95
96
97
98 private BuildAgentReleaseManager buildAgentReleaseManager;
99
100
101
102
103 private BuildAgentManager buildAgentManager;
104
105
106
107
108 private BuildAgentPurgeManager purgeManager;
109
110 public void buildProjects( List<Map<String, Object>> projectsBuildContext )
111 throws ContinuumBuildAgentException
112 {
113 List<BuildContext> buildContextList = initializeBuildContext( projectsBuildContext );
114
115 PrepareBuildProjectsTask task = createPrepareBuildProjectsTask( buildContextList );
116
117 if ( task == null )
118 {
119 return;
120 }
121
122 try
123 {
124 log.info( "Adding project group {} to prepare build queue", task.getProjectGroupId() );
125 buildAgentTaskQueueManager.getPrepareBuildQueue().put( task );
126 }
127 catch ( TaskQueueException e )
128 {
129 throw new ContinuumBuildAgentException( "Error while enqueuing projects", e );
130 }
131
132 }
133
134 public List<Map<String, String>> getAvailableInstallations()
135 throws ContinuumBuildAgentException
136 {
137 List<Map<String, String>> installationsList = new ArrayList<Map<String, String>>();
138
139 List<Installation> installations = buildAgentConfigurationService.getAvailableInstallations();
140
141 for ( Installation installation : installations )
142 {
143 Map<String, String> map = new HashMap<String, String>();
144
145 if ( StringUtils.isBlank( installation.getName() ) )
146 {
147 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_NAME, "" );
148 }
149 else
150 {
151 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_NAME, installation.getName() );
152 }
153
154 if ( StringUtils.isBlank( installation.getType() ) )
155 {
156 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_TYPE, "" );
157 }
158 else
159 {
160 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_TYPE, installation.getType() );
161 }
162
163 if ( StringUtils.isBlank( installation.getVarName() ) )
164 {
165 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_NAME, "" );
166 }
167 else
168 {
169 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_VALUE, installation.getVarValue() );
170 }
171
172 if ( StringUtils.isBlank( installation.getVarValue() ) )
173 {
174 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_VALUE, "" );
175 }
176 else
177 {
178 map.put( ContinuumBuildAgentUtil.KEY_INSTALLATION_VAR_VALUE, installation.getVarValue() );
179 }
180
181 installationsList.add( map );
182 }
183
184 return installationsList;
185 }
186
187 public Map<String, Object> getBuildResult( int projectId )
188 throws ContinuumBuildAgentException
189 {
190 log.debug( "Get build result of project {}", projectId );
191
192 Map<String, Object> result = new HashMap<String, Object>();
193
194 int currentBuildId = 0;
195
196 try
197 {
198 log.debug( "Get current build project" );
199 currentBuildId = buildAgentTaskQueueManager.getIdOfProjectCurrentlyBuilding();
200 }
201 catch ( TaskQueueManagerException e )
202 {
203 throw new ContinuumBuildAgentException( e.getMessage(), e );
204 }
205
206 log.debug( "Check if project {} is the one currently building in the agent", projectId );
207 if ( projectId == currentBuildId )
208 {
209 BuildContext buildContext = buildContextManager.getBuildContext( projectId );
210
211 result.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, buildContext.getProjectId() );
212 result.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, buildContext.getBuildDefinitionId() );
213 result.put( ContinuumBuildAgentUtil.KEY_TRIGGER, buildContext.getTrigger() );
214 result.put( ContinuumBuildAgentUtil.KEY_USERNAME, buildContext.getUsername() );
215
216 BuildResult buildResult = buildContext.getBuildResult();
217
218 if ( buildResult != null )
219 {
220 if ( buildResult.getStartTime() <= 0 )
221 {
222 result.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString(
223 buildContext.getBuildStartTime() ) );
224 }
225 else
226 {
227 result.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString( buildResult.getStartTime() ) );
228 }
229
230 if ( buildResult.getError() == null )
231 {
232 result.put( ContinuumBuildAgentUtil.KEY_BUILD_ERROR, "" );
233 }
234 else
235 {
236 result.put( ContinuumBuildAgentUtil.KEY_BUILD_ERROR, buildResult.getError() );
237 }
238
239 result.put( ContinuumBuildAgentUtil.KEY_BUILD_STATE, buildResult.getState() );
240 result.put( ContinuumBuildAgentUtil.KEY_END_TIME, Long.toString( buildResult.getEndTime() ) );
241 result.put( ContinuumBuildAgentUtil.KEY_BUILD_EXIT_CODE, buildResult.getExitCode() );
242 }
243 else
244 {
245 result.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString( buildContext.getBuildStartTime() ) );
246 result.put( ContinuumBuildAgentUtil.KEY_END_TIME, Long.toString( 0 ) );
247 result.put( ContinuumBuildAgentUtil.KEY_BUILD_STATE, ContinuumProjectState.BUILDING );
248 result.put( ContinuumBuildAgentUtil.KEY_BUILD_ERROR, "" );
249 result.put( ContinuumBuildAgentUtil.KEY_BUILD_EXIT_CODE, 0 );
250 }
251
252 String buildOutput = getBuildOutputText( projectId );
253 if ( buildOutput == null )
254 {
255 result.put( ContinuumBuildAgentUtil.KEY_BUILD_OUTPUT, "" );
256 }
257 else
258 {
259 result.put( ContinuumBuildAgentUtil.KEY_BUILD_OUTPUT, buildOutput );
260 }
261
262 result.put( ContinuumBuildAgentUtil.KEY_SCM_RESULT, ContinuumBuildAgentUtil.createScmResult(
263 buildContext ) );
264 }
265 else
266 {
267 log.debug( "Unable to get build result because project {} is not currently building in the agent",
268 projectId );
269 }
270 return result;
271 }
272
273 public void cancelBuild()
274 throws ContinuumBuildAgentException
275 {
276 try
277 {
278 log.debug( "Cancelling current build" );
279 buildAgentTaskQueueManager.cancelBuild();
280 }
281 catch ( TaskQueueManagerException e )
282 {
283 throw new ContinuumBuildAgentException( e.getMessage(), e );
284 }
285 }
286
287 public String generateWorkingCopyContent( int projectId, String userDirectory, String baseUrl,
288 String imagesBaseUrl )
289 throws ContinuumBuildAgentException
290 {
291 File workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId );
292
293 try
294 {
295 List<File> files = ContinuumBuildAgentUtil.getFiles( userDirectory, workingDirectory );
296 return generator.generate( files, baseUrl, imagesBaseUrl, workingDirectory );
297 }
298 catch ( ContinuumException e )
299 {
300 log.error( "Failed to generate working copy content", e );
301 }
302
303 return "";
304 }
305
306 public Map<String, Object> getProjectFile( int projectId, String directory, String filename )
307 throws ContinuumBuildAgentException
308 {
309 Map<String, Object> projectFile = new HashMap<String, Object>();
310
311 String relativePath = "\\.\\./";
312 Pattern pattern = Pattern.compile( relativePath );
313 Matcher matcher = pattern.matcher( directory );
314 String filteredDirectory = matcher.replaceAll( "" );
315
316 matcher = pattern.matcher( filename );
317 String filteredFilename = matcher.replaceAll( "" );
318
319 File workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId );
320
321 File fileDirectory = new File( workingDirectory, filteredDirectory );
322
323 File userFile = new File( fileDirectory, filteredFilename );
324 byte[] downloadFile;
325
326 try
327 {
328 downloadFile = FileUtils.readFileToByteArray( userFile );
329 }
330 catch ( IOException e )
331 {
332 throw new ContinuumBuildAgentException( "Can't read file: " + filename );
333 }
334
335 MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
336 mimeTypesMap.addMimeTypes( "application/java-archive jar war ear" );
337 mimeTypesMap.addMimeTypes( "application/java-class class" );
338 mimeTypesMap.addMimeTypes( "image/png png" );
339
340 String mimeType = mimeTypesMap.getContentType( userFile );
341 String fileContent;
342 boolean isStream = false;
343
344 if ( ( mimeType.indexOf( "image" ) >= 0 ) || ( mimeType.indexOf( "java-archive" ) >= 0 ) ||
345 ( mimeType.indexOf( "java-class" ) >= 0 ) || ( userFile.length() > 100000 ) )
346 {
347 fileContent = "";
348 isStream = true;
349 }
350 else
351 {
352 try
353 {
354 fileContent = FileUtils.readFileToString( userFile );
355 }
356 catch ( IOException e )
357 {
358 throw new ContinuumBuildAgentException( "Can't read file " + filename, e );
359 }
360 }
361
362 projectFile.put( "downloadFileName", userFile.getName() );
363 projectFile.put( "downloadFileLength", Long.toString( userFile.length() ) );
364 projectFile.put( "downloadFile", downloadFile );
365 projectFile.put( "mimeType", mimeType );
366 projectFile.put( "fileContent", fileContent );
367 projectFile.put( "isStream", isStream );
368
369 return projectFile;
370 }
371
372 public Map<String, Object> getReleasePluginParameters( int projectId, String pomFilename )
373 throws ContinuumBuildAgentException
374 {
375 String workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId ).getPath();
376
377 try
378 {
379 log.debug( "Getting release plugin parameters of project {}", projectId );
380 return ReleaseUtil.getReleasePluginParameters( workingDirectory, pomFilename );
381 }
382 catch ( Exception e )
383 {
384 throw new ContinuumBuildAgentException( "Error getting release plugin parameters from pom file", e );
385 }
386 }
387
388 public List<Map<String, String>> processProject( int projectId, String pomFilename, boolean autoVersionSubmodules )
389 throws ContinuumBuildAgentException
390 {
391 List<Map<String, String>> projects = new ArrayList<Map<String, String>>();
392
393 String workingDirectory = buildAgentConfigurationService.getWorkingDirectory( projectId ).getPath();
394
395 try
396 {
397 ReleaseUtil.processProject( workingDirectory, pomFilename, autoVersionSubmodules, projects );
398 }
399 catch ( Exception e )
400 {
401 throw new ContinuumBuildAgentException( "Unable to process project " + projectId, e );
402 }
403
404 return projects;
405 }
406
407 public String releasePrepare( Map project, Properties properties, Map releaseVersion, Map developmentVersion,
408 Map<String, String> environments, String username )
409 throws ContinuumBuildAgentException
410 {
411 try
412 {
413 log.debug( "Preparing release" );
414 return buildAgentReleaseManager.releasePrepare( project, properties, releaseVersion, developmentVersion,
415 environments, username );
416 }
417 catch ( ContinuumReleaseException e )
418 {
419 throw new ContinuumBuildAgentException( "Unable to prepare release", e );
420 }
421 }
422
423 public Map<String, Object> getReleaseResult( String releaseId )
424 throws ContinuumBuildAgentException
425 {
426 log.debug( "Getting release result of release {}", releaseId );
427 ReleaseResult result = buildAgentReleaseManager.getReleaseResult( releaseId );
428
429 Map<String, Object> map = new HashMap<String, Object>();
430 map.put( ContinuumBuildAgentUtil.KEY_START_TIME, Long.toString( result.getStartTime() ) );
431 map.put( ContinuumBuildAgentUtil.KEY_END_TIME, Long.toString( result.getEndTime() ) );
432 map.put( ContinuumBuildAgentUtil.KEY_RELEASE_RESULT_CODE, result.getResultCode() );
433 map.put( ContinuumBuildAgentUtil.KEY_RELEASE_OUTPUT, result.getOutput() );
434
435 return map;
436 }
437
438 public Map<String, Object> getListener( String releaseId )
439 throws ContinuumBuildAgentException
440 {
441 return buildAgentReleaseManager.getListener( releaseId );
442 }
443
444 public void removeListener( String releaseId )
445 {
446 buildAgentReleaseManager.removeListener( releaseId );
447 }
448
449 public String getPreparedReleaseName( String releaseId )
450 {
451 return buildAgentReleaseManager.getPreparedReleaseName( releaseId );
452 }
453
454 public void releasePerform( String releaseId, String goals, String arguments, boolean useReleaseProfile,
455 Map repository, String username )
456 throws ContinuumBuildAgentException
457 {
458 try
459 {
460 log.debug( "Performing release" );
461 buildAgentReleaseManager.releasePerform( releaseId, goals, arguments, useReleaseProfile, repository,
462 username );
463 }
464 catch ( ContinuumReleaseException e )
465 {
466 throw new ContinuumBuildAgentException( "Unable to perform release " + releaseId, e );
467 }
468 }
469
470 public String releasePerformFromScm( String goals, String arguments, boolean useReleaseProfile, Map repository,
471 String scmUrl, String scmUsername, String scmPassword, String scmTag,
472 String scmTagBase, Map<String, String> environments, String username )
473 throws ContinuumBuildAgentException
474 {
475 try
476 {
477 log.debug( "Performing release from scm" );
478 return buildAgentReleaseManager.releasePerformFromScm( goals, arguments, useReleaseProfile, repository,
479 scmUrl, scmUsername, scmPassword, scmTag, scmTagBase,
480 environments, username );
481 }
482 catch ( ContinuumReleaseException e )
483 {
484 throw new ContinuumBuildAgentException( "Unable to perform release from scm", e );
485 }
486 }
487
488 public String releaseCleanup( String releaseId )
489 throws ContinuumBuildAgentException
490 {
491 log.debug( "Cleanup release {}", releaseId );
492 return buildAgentReleaseManager.releaseCleanup( releaseId );
493 }
494
495 public void releaseRollback( String releaseId, int projectId )
496 throws ContinuumBuildAgentException
497 {
498 try
499 {
500 log.debug( "Release rollback release {} with project {}", releaseId, projectId );
501 buildAgentReleaseManager.releaseRollback( releaseId, projectId );
502 }
503 catch ( ContinuumReleaseException e )
504 {
505 throw new ContinuumBuildAgentException( e );
506 }
507 }
508
509 public int getBuildSizeOfAgent()
510 {
511 int size = 0;
512
513 try
514 {
515 log.debug( "Getting number of projects in any queue" );
516
517 if ( buildAgentTaskQueueManager.getCurrentProjectInBuilding() != null )
518 {
519 size++;
520 }
521
522 PrepareBuildProjectsTask currentPrepareBuild = buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
523
524 if ( currentPrepareBuild != null )
525 {
526
527 size = size + currentPrepareBuild.getBuildContexts().size();
528 }
529
530 size = size + buildAgentTaskQueueManager.getProjectsInBuildQueue().size();
531
532 for ( PrepareBuildProjectsTask prepareBuildTask : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
533 {
534 if ( prepareBuildTask != null )
535 {
536 size = size + prepareBuildTask.getBuildContexts().size();
537 }
538 }
539 }
540 catch ( TaskQueueManagerException e )
541 {
542 log.error( "Error occurred while getting build size of agent" );
543 }
544
545 return size;
546 }
547
548 public List<Map<String, Object>> getProjectsInPrepareBuildQueue()
549 throws ContinuumBuildAgentException
550 {
551 try
552 {
553 log.debug( "Getting projects in prepare build queue" );
554 List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
555
556 for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
557 {
558 Map<String, Object> map = new HashMap<String, Object>();
559 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
560 map.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ID, new Integer( task.getScmRootId() ) );
561 map.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ADDRESS, task.getScmRootAddress() );
562 map.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
563 map.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
564
565 projects.add( map );
566 }
567
568 return projects;
569 }
570 catch ( TaskQueueManagerException e )
571 {
572 log.error( "Error occurred while retrieving projects in prepare build queue", e );
573 throw new ContinuumBuildAgentException( "Error occurred while retrieving projects in prepare build queue",
574 e );
575 }
576 }
577
578 public List<Map<String, Object>> getProjectsAndBuildDefinitionsInPrepareBuildQueue()
579 throws ContinuumBuildAgentException
580 {
581 try
582 {
583 log.debug( "Getting projects in prepare build queue" );
584 List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
585
586 for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
587 {
588 for ( BuildContext context : task.getBuildContexts() )
589 {
590 Map<String, Object> map = new HashMap<String, Object>();
591
592 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, context.getProjectId() );
593 map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, context.getBuildDefinitionId() );
594
595 projects.add( map );
596 }
597 }
598
599 return projects;
600 }
601 catch ( TaskQueueManagerException e )
602 {
603 log.error( "Error occurred while retrieving projects in prepare build queue", e );
604 throw new ContinuumBuildAgentException( "Error occurred while retrieving projects in prepare build queue",
605 e );
606 }
607 }
608
609 public List<Map<String, Object>> getProjectsInBuildQueue()
610 throws ContinuumBuildAgentException
611 {
612 try
613 {
614 log.debug( "Getting projects in build queue" );
615 List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
616
617 for ( BuildProjectTask task : buildAgentTaskQueueManager.getProjectsInBuildQueue() )
618 {
619 Map<String, Object> map = new HashMap<String, Object>();
620 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, new Integer( task.getProjectId() ) );
621 map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, new Integer( task.getBuildDefinitionId() ) );
622 map.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
623 map.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
624 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
625 map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_LABEL, task.getBuildDefinitionLabel() );
626
627 projects.add( map );
628 }
629
630 return projects;
631 }
632 catch ( TaskQueueManagerException e )
633 {
634 log.error( "Error occurred while retrieving projects in build queue", e );
635 throw new ContinuumBuildAgentException( "Error occurred while retrieving projects in build queue", e );
636 }
637 }
638
639 public Map<String, Object> getProjectCurrentlyPreparingBuild()
640 throws ContinuumBuildAgentException
641 {
642 try
643 {
644 log.debug( "Get project currently preparing build" );
645 Map<String, Object> project = new HashMap<String, Object>();
646
647 PrepareBuildProjectsTask task = buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
648
649 if ( task != null )
650 {
651 project.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
652 project.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ID, new Integer( task.getScmRootId() ) );
653 project.put( ContinuumBuildAgentUtil.KEY_SCM_ROOT_ADDRESS, task.getScmRootAddress() );
654 project.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
655 project.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
656 }
657
658 return project;
659 }
660 catch ( TaskQueueManagerException e )
661 {
662 log.error( "Error occurred while retrieving current project in prepare build", e );
663 throw new ContinuumBuildAgentException( "Error occurred while retrieving current project in prepare build",
664 e );
665 }
666 }
667
668 public List<Map<String, Object>> getProjectsAndBuildDefinitionsCurrentlyPreparingBuild()
669 throws ContinuumBuildAgentException
670 {
671 try
672 {
673 log.debug( "Getting projects currently preparing build" );
674 List<Map<String, Object>> projects = new ArrayList<Map<String, Object>>();
675
676 PrepareBuildProjectsTask task = buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
677
678 if ( task != null )
679 {
680 for ( BuildContext context : task.getBuildContexts() )
681 {
682 Map<String, Object> map = new HashMap<String, Object>();
683
684 map.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, context.getProjectId() );
685 map.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, context.getBuildDefinitionId() );
686
687 projects.add( map );
688 }
689 }
690
691 return projects;
692 }
693 catch ( TaskQueueManagerException e )
694 {
695 log.error( "Error occurred while retrieving current projects in prepare build", e );
696 throw new ContinuumBuildAgentException( "Error occurred while retrieving current projects in prepare build",
697 e );
698 }
699 }
700
701 public Map<String, Object> getProjectCurrentlyBuilding()
702 throws ContinuumBuildAgentException
703 {
704 try
705 {
706 log.debug( "Getting currently building project" );
707 Map<String, Object> project = new HashMap<String, Object>();
708
709 BuildProjectTask task = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
710
711 if ( task != null )
712 {
713 project.put( ContinuumBuildAgentUtil.KEY_PROJECT_ID, new Integer( task.getProjectId() ) );
714 project.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_ID, new Integer(
715 task.getBuildDefinitionId() ) );
716 project.put( ContinuumBuildAgentUtil.KEY_TRIGGER, task.getBuildTrigger().getTrigger() );
717 project.put( ContinuumBuildAgentUtil.KEY_USERNAME, task.getBuildTrigger().getTriggeredBy() );
718 project.put( ContinuumBuildAgentUtil.KEY_PROJECT_GROUP_ID, new Integer( task.getProjectGroupId() ) );
719 project.put( ContinuumBuildAgentUtil.KEY_BUILD_DEFINITION_LABEL, task.getBuildDefinitionLabel() );
720 }
721
722 return project;
723 }
724 catch ( TaskQueueManagerException e )
725 {
726 log.error( "Error occurred while retrieving current project in building", e );
727 throw new ContinuumBuildAgentException( "Error occurred while retrieving current project in building", e );
728 }
729 }
730
731 public boolean isProjectGroupInQueue( int projectGroupId )
732 {
733 try
734 {
735 log.debug( "Checking if project group is in any queue", projectGroupId );
736 for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
737 {
738 if ( task.getProjectGroupId() == projectGroupId )
739 {
740 log.debug( "projectGroup {} is in prepare build queue", projectGroupId );
741 return true;
742 }
743 }
744
745 PrepareBuildProjectsTask currentPrepareBuildTask =
746 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
747
748 if ( currentPrepareBuildTask != null && currentPrepareBuildTask.getProjectGroupId() == projectGroupId )
749 {
750 log.debug( "projectGroup {} is currently preparing build", projectGroupId );
751 return true;
752 }
753
754 for ( BuildProjectTask task : buildAgentTaskQueueManager.getProjectsInBuildQueue() )
755 {
756 if ( task.getProjectGroupId() == projectGroupId )
757 {
758 log.debug( "projectGroup {} is in build queue", projectGroupId );
759 return true;
760 }
761 }
762
763 BuildProjectTask currentBuildTask = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
764
765 if ( currentBuildTask != null && currentBuildTask.getProjectGroupId() == projectGroupId )
766 {
767 log.debug( "projectGroup {} is currently building", projectGroupId );
768 return true;
769 }
770 }
771 catch ( TaskQueueManagerException e )
772 {
773 log.error( "Error while checking if project group " + projectGroupId + " is queued in agent", e );
774 }
775
776 return false;
777 }
778
779 public boolean isProjectScmRootInQueue( int projectScmRootId, List<Integer> projectIds )
780 {
781 try
782 {
783 log.debug( "Checking if projects {} is in any queue", projectIds );
784 PrepareBuildProjectsTask currentPrepareBuildTask =
785 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
786
787 if ( currentPrepareBuildTask != null && currentPrepareBuildTask.getScmRootId() == projectScmRootId )
788 {
789 return true;
790 }
791
792 BuildProjectTask currentBuildTask = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
793
794 if ( currentBuildTask != null )
795 {
796 int projectId = currentBuildTask.getProjectId();
797
798 for ( Integer pid : projectIds )
799 {
800 if ( pid == projectId )
801 {
802 return true;
803 }
804 }
805 }
806
807 for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
808 {
809 if ( task.getScmRootId() == projectScmRootId )
810 {
811 return true;
812 }
813 }
814
815 for ( BuildProjectTask task : buildAgentTaskQueueManager.getProjectsInBuildQueue() )
816 {
817 int projectId = task.getProjectId();
818
819 for ( Integer pid : projectIds )
820 {
821 if ( pid == projectId )
822 {
823 return true;
824 }
825 }
826 }
827 }
828 catch ( TaskQueueManagerException e )
829 {
830 log.error( "Error while checking if project scm root " + projectScmRootId + " is queued in agent", e );
831 }
832
833 return false;
834 }
835
836 public boolean isProjectGroupInPrepareBuildQueue( int projectGroupId )
837 {
838 try
839 {
840 log.debug( "Checking if project group {} is in prepare build queue", projectGroupId );
841 for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
842 {
843 if ( task.getProjectGroupId() == projectGroupId )
844 {
845 return true;
846 }
847 }
848 }
849 catch ( TaskQueueManagerException e )
850 {
851 log.error(
852 "Error while checking if project group " + projectGroupId + " is in prepare build queue in agent", e );
853 }
854
855 return false;
856 }
857
858 public boolean isProjectInPrepareBuildQueue( int projectId, int buildDefinitionId )
859 {
860 try
861 {
862 log.debug( "Checking if projectId={}, buildDefinitionId={} is in prepare build queue", projectId,
863 buildDefinitionId );
864 for ( PrepareBuildProjectsTask task : buildAgentTaskQueueManager.getProjectsInPrepareBuildQueue() )
865 {
866 if ( task != null )
867 {
868 for ( BuildContext context : task.getBuildContexts() )
869 {
870 if ( context.getProjectId() == projectId &&
871 ( buildDefinitionId == -1 || context.getBuildDefinitionId() == buildDefinitionId ) )
872 {
873 log.debug( "projectId={}, buildDefinitionId={} is in prepare build queue" );
874 return true;
875 }
876 }
877 }
878 }
879 }
880 catch ( TaskQueueManagerException e )
881 {
882 log.error( "Error while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
883 " is in prepare build queue in agent", e );
884 }
885
886 return false;
887 }
888
889 public boolean isProjectGroupCurrentlyPreparingBuild( int projectGroupId )
890 {
891 try
892 {
893 log.debug( "Checking if project group {} currently preparing build", projectGroupId );
894 PrepareBuildProjectsTask currentPrepareBuildTask =
895 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
896
897 if ( currentPrepareBuildTask != null && currentPrepareBuildTask.getProjectGroupId() == projectGroupId )
898 {
899 return true;
900 }
901 }
902 catch ( TaskQueueManagerException e )
903 {
904 log.error(
905 "Error while checking if project group " + projectGroupId + " is currently preparing build in agent",
906 e );
907 }
908
909 return false;
910 }
911
912 public boolean isProjectCurrentlyPreparingBuild( int projectId, int buildDefinitionId )
913 {
914 try
915 {
916 log.debug( "Checking if projectId={}, buildDefinitionId={} currently preparing build", projectId,
917 buildDefinitionId );
918 PrepareBuildProjectsTask currentPrepareBuildTask =
919 buildAgentTaskQueueManager.getCurrentProjectInPrepareBuild();
920
921 if ( currentPrepareBuildTask != null )
922 {
923 for ( BuildContext context : currentPrepareBuildTask.getBuildContexts() )
924 {
925 if ( context.getProjectId() == projectId &&
926 ( buildDefinitionId == -1 || context.getBuildDefinitionId() == buildDefinitionId ) )
927 {
928 log.debug( "projectId={}, buildDefinitionId={} is currently preparing build" );
929 return true;
930 }
931 }
932 }
933 }
934 catch ( TaskQueueManagerException e )
935 {
936 log.error( "Error while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
937 " is currently preparing build in agent", e );
938 }
939
940 return false;
941 }
942
943 public boolean isProjectCurrentlyBuilding( int projectId, int buildDefinitionId )
944 {
945 try
946 {
947 log.debug( "Checking if projectId={}, buildDefinitionId={} is currently building", projectId,
948 buildDefinitionId );
949 BuildProjectTask currentBuildTask = buildAgentTaskQueueManager.getCurrentProjectInBuilding();
950
951 if ( currentBuildTask != null && currentBuildTask.getProjectId() == projectId &&
952 ( buildDefinitionId == -1 || currentBuildTask.getBuildDefinitionId() == buildDefinitionId ) )
953 {
954 log.debug( "projectId={}, buildDefinitionId={} is currently building" );
955 return true;
956 }
957 }
958 catch ( TaskQueueManagerException e )
959 {
960 log.error(
961 "Error occurred while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
962 " is currently building in agent", e );
963 }
964
965 return false;
966 }
967
968 public boolean isProjectInBuildQueue( int projectId, int buildDefinitionId )
969 {
970 try
971 {
972 log.debug( "Checking if projectId={}, buildDefinitionId={} is in build queue", projectId,
973 buildDefinitionId );
974 List<BuildProjectTask> buildTasks = buildAgentTaskQueueManager.getProjectsInBuildQueue();
975
976 if ( buildTasks != null )
977 {
978 for ( BuildProjectTask task : buildTasks )
979 {
980 if ( task.getProjectId() == projectId &&
981 ( buildDefinitionId == -1 || task.getBuildDefinitionId() == buildDefinitionId ) )
982 {
983 log.debug( "projectId={}, buildDefinitionId={} is in build queue" );
984 return true;
985 }
986 }
987 }
988 }
989 catch ( TaskQueueManagerException e )
990 {
991 log.error(
992 "Error occurred while checking if projectId=" + projectId + ", buildDefinitionId=" + buildDefinitionId +
993 " is in build queue of agent", e );
994 }
995
996 return false;
997 }
998
999 public boolean removeFromPrepareBuildQueue( int projectGroupId, int scmRootId )
1000 throws ContinuumBuildAgentException
1001 {
1002 try
1003 {
1004 log.info( "Removing project group {} from prepare build queue", projectGroupId );
1005 return buildAgentTaskQueueManager.removeFromPrepareBuildQueue( projectGroupId, scmRootId );
1006 }
1007 catch ( TaskQueueManagerException e )
1008 {
1009 log.error( "Error occurred while removing projects from prepare build queue", e );
1010 throw new ContinuumBuildAgentException( "Error occurred while removing projects from prepare build queue",
1011 e );
1012 }
1013 }
1014
1015 public void removeFromPrepareBuildQueue( List<String> hashCodes )
1016 throws ContinuumBuildAgentException
1017 {
1018 try
1019 {
1020 log.info( "Removing project groups {} from prepare build queue", hashCodes );
1021 buildAgentTaskQueueManager.removeFromPrepareBuildQueue( listToIntArray( hashCodes ) );
1022 }
1023 catch ( TaskQueueManagerException e )
1024 {
1025 log.error( "Error occurred while removing projects from prepare build queue", e );
1026 throw new ContinuumBuildAgentException( "Error occurred while removing projects from prepare build queue",
1027 e );
1028 }
1029 }
1030
1031 public boolean removeFromBuildQueue( int projectId, int buildDefinitionId )
1032 throws ContinuumBuildAgentException
1033 {
1034 try
1035 {
1036 log.info( "Removing project {} with buildDefinition {} from build queue", projectId, buildDefinitionId );
1037 return buildAgentTaskQueueManager.removeFromBuildQueue( projectId, buildDefinitionId );
1038 }
1039 catch ( TaskQueueManagerException e )
1040 {
1041 log.error( "Error occurred while removing project from build queue", e );
1042 throw new ContinuumBuildAgentException( "Error occurred while removing project from build queue ", e );
1043 }
1044 }
1045
1046 public void removeFromBuildQueue( List<String> hashCodes )
1047 throws ContinuumBuildAgentException
1048 {
1049 try
1050 {
1051 log.info( "Removing projects {} from build queue", hashCodes );
1052 buildAgentTaskQueueManager.removeFromBuildQueue( listToIntArray( hashCodes ) );
1053 }
1054 catch ( TaskQueueManagerException e )
1055 {
1056 log.error( "Error occurred while removing projects from build queue", e );
1057 throw new ContinuumBuildAgentException( "Error occurred while removing project from build queue ", e );
1058 }
1059 }
1060
1061 public boolean ping()
1062 throws ContinuumBuildAgentException
1063 {
1064 try
1065 {
1066
1067 return buildAgentManager.pingMaster();
1068 }
1069 catch ( ContinuumException e )
1070 {
1071 throw new ContinuumBuildAgentException( e.getMessage() );
1072 }
1073 }
1074
1075 public String getBuildAgentPlatform()
1076 throws ContinuumBuildAgentException
1077 {
1078 try
1079 {
1080 log.debug( "Getting build agent platform" );
1081 return System.getProperty( "os.name" );
1082 }
1083 catch ( Exception e )
1084 {
1085 log.error( "Error in when trying to get build agent's platform", e );
1086 throw new ContinuumBuildAgentException( "Error in when trying to get build agent's platform", e );
1087 }
1088 }
1089
1090 public boolean isExecutingBuild()
1091 {
1092 return getBuildSizeOfAgent() > 0;
1093 }
1094
1095 public boolean isExecutingRelease()
1096 throws ContinuumBuildAgentException
1097 {
1098 try
1099 {
1100 return buildAgentReleaseManager.getReleaseManager().isExecutingRelease();
1101 }
1102 catch ( Exception e )
1103 {
1104 throw new ContinuumBuildAgentException( e.getMessage(), e );
1105 }
1106 }
1107
1108 public void executeDirectoryPurge( String directoryType, int daysOlder, int retentionCount, boolean deleteAll )
1109 throws ContinuumBuildAgentException
1110 {
1111 String logMsgFormat =
1112 "Directory purge [directoryType={0}, daysOlder={1}, retentionCount={2}, deleteAll={3}] not possible; {4}";
1113 if ( isExecutingBuild() )
1114 {
1115 log.info( MessageFormat.format( logMsgFormat, directoryType, daysOlder, retentionCount, deleteAll,
1116 "Build Agent busy" ) );
1117 return;
1118 }
1119
1120 try
1121 {
1122 if ( isExecutingRelease() )
1123 {
1124 log.info( MessageFormat.format( logMsgFormat, directoryType, daysOlder, retentionCount, deleteAll,
1125 "Build Agent is executing a release." ) );
1126 return;
1127 }
1128 }
1129 catch ( ContinuumBuildAgentException e )
1130 {
1131 if ( isExecutingRelease() )
1132 {
1133 log.info( MessageFormat.format( logMsgFormat, directoryType, daysOlder, retentionCount, deleteAll,
1134 "Unable to determine if Build Agent is executing a release." ) );
1135 return;
1136 }
1137 }
1138
1139 try
1140 {
1141 purgeManager.executeDirectoryPurge( directoryType, daysOlder, retentionCount, deleteAll );
1142 }
1143 catch ( Exception e )
1144 {
1145 throw new ContinuumBuildAgentException( e.getMessage(), e );
1146 }
1147 }
1148
1149 private List<BuildContext> initializeBuildContext( List<Map<String, Object>> projectsBuildContext )
1150 {
1151 List<BuildContext> buildContext = new ArrayList<BuildContext>();
1152
1153 for ( Map<String, Object> map : projectsBuildContext )
1154 {
1155 BuildContext context = new BuildContext();
1156 context.setProjectId( ContinuumBuildAgentUtil.getProjectId( map ) );
1157 context.setProjectVersion( ContinuumBuildAgentUtil.getProjectVersion( map ) );
1158 context.setBuildDefinitionId( ContinuumBuildAgentUtil.getBuildDefinitionId( map ) );
1159 context.setBuildFile( ContinuumBuildAgentUtil.getBuildFile( map ) );
1160 context.setExecutorId( ContinuumBuildAgentUtil.getExecutorId( map ) );
1161 context.setGoals( ContinuumBuildAgentUtil.getGoals( map ) );
1162 context.setArguments( ContinuumBuildAgentUtil.getArguments( map ) );
1163 context.setScmUrl( ContinuumBuildAgentUtil.getScmUrl( map ) );
1164 context.setScmUsername( ContinuumBuildAgentUtil.getScmUsername( map ) );
1165 context.setScmPassword( ContinuumBuildAgentUtil.getScmPassword( map ) );
1166 context.setBuildFresh( ContinuumBuildAgentUtil.isBuildFresh( map ) );
1167 context.setProjectGroupId( ContinuumBuildAgentUtil.getProjectGroupId( map ) );
1168 context.setProjectGroupName( ContinuumBuildAgentUtil.getProjectGroupName( map ) );
1169 context.setScmRootAddress( ContinuumBuildAgentUtil.getScmRootAddress( map ) );
1170 context.setScmRootId( ContinuumBuildAgentUtil.getScmRootId( map ) );
1171 context.setProjectName( ContinuumBuildAgentUtil.getProjectName( map ) );
1172 context.setProjectState( ContinuumBuildAgentUtil.getProjectState( map ) );
1173 context.setTrigger( ContinuumBuildAgentUtil.getTrigger( map ) );
1174 context.setUsername( ContinuumBuildAgentUtil.getUsername( map ) );
1175 context.setLocalRepository( ContinuumBuildAgentUtil.getLocalRepository( map ) );
1176 context.setBuildNumber( ContinuumBuildAgentUtil.getBuildNumber( map ) );
1177 context.setOldScmResult( getScmResult( ContinuumBuildAgentUtil.getOldScmChanges( map ) ) );
1178 context.setLatestUpdateDate( ContinuumBuildAgentUtil.getLatestUpdateDate( map ) );
1179 context.setBuildAgentUrl( ContinuumBuildAgentUtil.getBuildAgentUrl( map ) );
1180 context.setMaxExecutionTime( ContinuumBuildAgentUtil.getMaxExecutionTime( map ) );
1181 context.setBuildDefinitionLabel( ContinuumBuildAgentUtil.getBuildDefinitionLabel( map ) );
1182 context.setScmTag( ContinuumBuildAgentUtil.getScmTag( map ) );
1183
1184 buildContext.add( context );
1185 }
1186
1187 buildContextManager.addBuildContexts( buildContext );
1188
1189 return buildContext;
1190 }
1191
1192 private String getBuildOutputText( int projectId )
1193 {
1194 try
1195 {
1196 File buildOutputFile = buildAgentConfigurationService.getBuildOutputFile( projectId );
1197
1198 if ( buildOutputFile.exists() )
1199 {
1200 return StringEscapeUtils.escapeHtml( FileUtils.readFileToString( buildOutputFile ) );
1201 }
1202 }
1203 catch ( Exception e )
1204 {
1205
1206 log.error( "Error retrieving build output file", e );
1207 }
1208
1209 return null;
1210 }
1211
1212 private ScmResult getScmResult( List<Map<String, Object>> scmChanges )
1213 {
1214 ScmResult scmResult = null;
1215
1216 if ( scmChanges != null && scmChanges.size() > 0 )
1217 {
1218 scmResult = new ScmResult();
1219
1220 for ( Map<String, Object> map : scmChanges )
1221 {
1222 ChangeSet changeSet = new ChangeSet();
1223 changeSet.setAuthor( ContinuumBuildAgentUtil.getChangeSetAuthor( map ) );
1224 changeSet.setComment( ContinuumBuildAgentUtil.getChangeSetComment( map ) );
1225 changeSet.setDate( ContinuumBuildAgentUtil.getChangeSetDate( map ) );
1226 setChangeFiles( changeSet, map );
1227 scmResult.addChange( changeSet );
1228 }
1229 }
1230
1231 return scmResult;
1232 }
1233
1234 private void setChangeFiles( ChangeSet changeSet, Map<String, Object> context )
1235 {
1236 List<Map<String, Object>> files = ContinuumBuildAgentUtil.getChangeSetFiles( context );
1237
1238 if ( files != null )
1239 {
1240 for ( Map<String, Object> map : files )
1241 {
1242 ChangeFile changeFile = new ChangeFile();
1243 changeFile.setName( ContinuumBuildAgentUtil.getChangeFileName( map ) );
1244 changeFile.setRevision( ContinuumBuildAgentUtil.getChangeFileRevision( map ) );
1245 changeFile.setStatus( ContinuumBuildAgentUtil.getChangeFileStatus( map ) );
1246
1247 changeSet.addFile( changeFile );
1248 }
1249 }
1250 }
1251
1252 private PrepareBuildProjectsTask createPrepareBuildProjectsTask( List<BuildContext> buildContexts )
1253 throws ContinuumBuildAgentException
1254 {
1255 if ( buildContexts != null && buildContexts.size() > 0 )
1256 {
1257 BuildContext context = buildContexts.get( 0 );
1258 return new PrepareBuildProjectsTask( buildContexts, new BuildTrigger( context.getTrigger(),
1259 context.getUsername() ),
1260 context.getProjectGroupId(), context.getScmRootAddress(),
1261 context.getScmRootId() );
1262 }
1263 else
1264 {
1265 log.info( "Nothing to build" );
1266 return null;
1267 }
1268 }
1269
1270 private int[] listToIntArray( List<String> strings )
1271 {
1272 if ( strings == null || strings.isEmpty() )
1273 {
1274 return new int[0];
1275 }
1276 int[] array = new int[0];
1277 for ( String intString : strings )
1278 {
1279 array = ArrayUtils.add( array, Integer.parseInt( intString ) );
1280 }
1281 return array;
1282 }
1283 }