View Javadoc

1   package org.apache.continuum.release.distributed.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.io.File;
23  import java.io.FileInputStream;
24  import java.io.FileWriter;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.net.MalformedURLException;
28  import java.net.URL;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Properties;
34  
35  import org.apache.continuum.configuration.BuildAgentConfiguration;
36  import org.apache.continuum.configuration.BuildAgentConfigurationException;
37  import org.apache.continuum.dao.BuildResultDao;
38  import org.apache.continuum.distributed.transport.slave.SlaveBuildAgentTransportClient;
39  import org.apache.continuum.model.repository.LocalRepository;
40  import org.apache.continuum.release.distributed.DistributedReleaseUtil;
41  import org.apache.continuum.release.model.PreparedRelease;
42  import org.apache.continuum.release.model.PreparedReleaseModel;
43  import org.apache.continuum.release.model.io.xpp3.ContinuumPrepareReleasesModelXpp3Reader;
44  import org.apache.continuum.release.model.io.xpp3.ContinuumPrepareReleasesModelXpp3Writer;
45  import org.apache.maven.continuum.configuration.ConfigurationService;
46  import org.apache.maven.continuum.installation.InstallationService;
47  import org.apache.maven.continuum.model.project.BuildResult;
48  import org.apache.maven.continuum.model.project.Project;
49  import org.apache.maven.continuum.release.ContinuumReleaseException;
50  import org.apache.maven.shared.release.ReleaseResult;
51  import org.codehaus.plexus.util.IOUtil;
52  import org.codehaus.plexus.util.StringUtils;
53  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
54  import org.slf4j.Logger;
55  import org.slf4j.LoggerFactory;
56  
57  /**
58   * @plexus.component role="org.apache.continuum.release.distributed.manager.DistributedReleaseManager"
59   */
60  public class DefaultDistributedReleaseManager
61      implements DistributedReleaseManager
62  {
63      private static final Logger log = LoggerFactory.getLogger( DefaultDistributedReleaseManager.class );
64  
65      public final String PREPARED_RELEASES_FILENAME = "prepared-releases.xml";
66  
67      /**
68       * @plexus.requirement
69       */
70      BuildResultDao buildResultDao;
71  
72      /**
73       * @plexus.requirement
74       */
75      InstallationService installationService;
76  
77      /**
78       * @plexus.requirement
79       */
80      ConfigurationService configurationService;
81  
82      private Map<String, Map<String, Object>> releasesInProgress;
83  
84      public Map getReleasePluginParameters( int projectId, String pomFilename )
85          throws ContinuumReleaseException, BuildAgentConfigurationException
86      {
87          BuildResult buildResult = buildResultDao.getLatestBuildResultForProject( projectId );
88  
89          String buildAgentUrl = buildResult.getBuildUrl();
90  
91          if ( !checkBuildAgent( buildAgentUrl ) )
92          {
93              throw new BuildAgentConfigurationException( buildAgentUrl );
94          }
95  
96          try
97          {
98              SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
99              return client.getReleasePluginParameters( projectId, pomFilename );
100         }
101         catch ( MalformedURLException e )
102         {
103             log.error( "Invalid build agent url " + buildAgentUrl );
104             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
105         }
106         catch ( Exception e )
107         {
108             log.error( "Failed to retrieve release plugin parameters", e );
109             throw new ContinuumReleaseException( "Failed to retrieve release plugin parameters", e );
110         }
111     }
112 
113     public List<Map<String, String>> processProject( int projectId, String pomFilename, boolean autoVersionSubmodules )
114         throws ContinuumReleaseException, BuildAgentConfigurationException
115     {
116         BuildResult buildResult = buildResultDao.getLatestBuildResultForProject( projectId );
117 
118         String buildAgentUrl = buildResult.getBuildUrl();
119 
120         if ( !checkBuildAgent( buildAgentUrl ) )
121         {
122             throw new BuildAgentConfigurationException( buildAgentUrl );
123         }
124 
125         try
126         {
127             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
128             return client.processProject( projectId, pomFilename, autoVersionSubmodules );
129         }
130         catch ( MalformedURLException e )
131         {
132             log.error( "Invalid build agent url " + buildAgentUrl );
133             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
134         }
135         catch ( Exception e )
136         {
137             log.error( "Failed to process project for releasing", e );
138             throw new ContinuumReleaseException( "Failed to process project for releasing", e );
139         }
140     }
141 
142     public String releasePrepare( Project project, Properties releaseProperties, Map<String, String> releaseVersion,
143                                   Map<String, String> developmentVersion, Map<String, String> environments )
144         throws ContinuumReleaseException, BuildAgentConfigurationException
145     {
146         BuildResult buildResult = buildResultDao.getLatestBuildResultForProject( project.getId() );
147 
148         String buildAgentUrl = buildResult.getBuildUrl();
149 
150         if ( !checkBuildAgent( buildAgentUrl ) )
151         {
152             throw new BuildAgentConfigurationException( buildAgentUrl );
153         }
154 
155         try
156         {
157             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
158             String releaseId =
159                 client.releasePrepare( createProjectMap( project ), createPropertiesMap( releaseProperties ),
160                                        releaseVersion, developmentVersion, environments );
161 
162             addReleasePrepare( releaseId, buildAgentUrl, releaseVersion.get( releaseId ) );
163 
164             addReleaseInProgress( releaseId, "prepare", project.getId() );
165 
166             return releaseId;
167         }
168         catch ( MalformedURLException e )
169         {
170             log.error( "Invalid build agent url " + buildAgentUrl );
171             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
172         }
173         catch ( Exception e )
174         {
175             log.error( "Failed to prepare release project " + project.getName(), e );
176             throw new ContinuumReleaseException( "Failed to prepare release project " + project.getName(), e );
177         }
178     }
179 
180     public ReleaseResult getReleaseResult( String releaseId )
181         throws ContinuumReleaseException, BuildAgentConfigurationException
182     {
183         String buildAgentUrl = getBuildAgentUrl( releaseId );
184 
185         if ( !checkBuildAgent( buildAgentUrl ) )
186         {
187             throw new BuildAgentConfigurationException( buildAgentUrl );
188         }
189 
190         try
191         {
192             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
193             Map<String, Object> result = client.getReleaseResult( releaseId );
194 
195             ReleaseResult releaseResult = new ReleaseResult();
196             releaseResult.setStartTime( DistributedReleaseUtil.getStartTime( result ) );
197             releaseResult.setEndTime( DistributedReleaseUtil.getEndTime( result ) );
198             releaseResult.setResultCode( DistributedReleaseUtil.getReleaseResultCode( result ) );
199             releaseResult.getOutputBuffer().append( DistributedReleaseUtil.getReleaseOutput( result ) );
200 
201             return releaseResult;
202         }
203         catch ( MalformedURLException e )
204         {
205             log.error( "Invalid build agent url " + buildAgentUrl );
206             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
207         }
208         catch ( Exception e )
209         {
210             log.error( "Failed to get release result of " + releaseId, e );
211             throw new ContinuumReleaseException( "Failed to get release result of " + releaseId, e );
212         }
213     }
214 
215     public Map getListener( String releaseId )
216         throws ContinuumReleaseException, BuildAgentConfigurationException
217     {
218         String buildAgentUrl = getBuildAgentUrl( releaseId );
219 
220         if ( !checkBuildAgent( buildAgentUrl ) )
221         {
222             throw new BuildAgentConfigurationException( buildAgentUrl );
223         }
224 
225         try
226         {
227             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
228             return client.getListener( releaseId );
229         }
230         catch ( MalformedURLException e )
231         {
232             log.error( "Invalid build agent url " + buildAgentUrl );
233             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
234         }
235         catch ( Exception e )
236         {
237             log.error( "Failed to get listener for " + releaseId, e );
238             throw new ContinuumReleaseException( "Failed to get listener for " + releaseId, e );
239         }
240     }
241 
242     public void removeListener( String releaseId )
243         throws ContinuumReleaseException, BuildAgentConfigurationException
244     {
245         String buildAgentUrl = getBuildAgentUrl( releaseId );
246 
247         if ( !checkBuildAgent( buildAgentUrl ) )
248         {
249             throw new BuildAgentConfigurationException( buildAgentUrl );
250         }
251 
252         try
253         {
254             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
255             client.removeListener( releaseId );
256         }
257         catch ( MalformedURLException e )
258         {
259             log.error( "Invalid build agent url " + buildAgentUrl );
260             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
261         }
262         catch ( Exception e )
263         {
264             log.error( "Failed to remove listener of " + releaseId, e );
265             throw new ContinuumReleaseException( "Failed to remove listener of " + releaseId, e );
266         }
267     }
268 
269     public String getPreparedReleaseName( String releaseId )
270         throws ContinuumReleaseException
271     {
272         String buildAgentUrl = getBuildAgentUrl( releaseId );
273 
274         if ( StringUtils.isBlank( buildAgentUrl ) )
275         {
276             log.info( "Unable to get prepared release name because no build agent found for " + releaseId );
277             return null;
278         }
279 
280         try
281         {
282             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
283             return client.getPreparedReleaseName( releaseId );
284         }
285         catch ( MalformedURLException e )
286         {
287             log.error( "Invalid build agent url " + buildAgentUrl );
288             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
289         }
290         catch ( Exception e )
291         {
292             log.error( "Failed to get prepared release name of " + releaseId, e );
293             throw new ContinuumReleaseException( "Failed to get prepared release name of " + releaseId, e );
294         }
295     }
296 
297     public void releasePerform( int projectId, String releaseId, String goals, String arguments,
298                                 boolean useReleaseProfile, LocalRepository repository )
299         throws ContinuumReleaseException, BuildAgentConfigurationException
300     {
301         String buildAgentUrl = getBuildAgentUrl( releaseId );
302 
303         if ( !checkBuildAgent( buildAgentUrl ) )
304         {
305             throw new BuildAgentConfigurationException( buildAgentUrl );
306         }
307 
308         if ( goals == null )
309         {
310             goals = "";
311         }
312 
313         if ( arguments == null )
314         {
315             arguments = "";
316         }
317 
318         Map<String, String> map = new HashMap<String, String>();
319 
320         if ( repository != null )
321         {
322             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY, repository.getLocation() );
323             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY_NAME, repository.getName() );
324             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY_LAYOUT, repository.getLayout() );
325         }
326 
327         try
328         {
329             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
330             client.releasePerform( releaseId, goals, arguments, useReleaseProfile, map );
331 
332             addReleaseInProgress( releaseId, "perform", projectId );
333         }
334         catch ( MalformedURLException e )
335         {
336             log.error( "Invalid build agent url " + buildAgentUrl );
337             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
338         }
339         catch ( Exception e )
340         {
341             log.error( "Failed to perform release of " + releaseId, e );
342             throw new ContinuumReleaseException( "Failed to perform release of " + releaseId, e );
343         }
344     }
345 
346     public void releasePerformFromScm( int projectId, String goals, String arguments, boolean useReleaseProfile,
347                                        LocalRepository repository, String scmUrl, String scmUsername,
348                                        String scmPassword, String scmTag, String scmTagBase, Map environments )
349         throws ContinuumReleaseException, BuildAgentConfigurationException
350     {
351         BuildResult buildResult = buildResultDao.getLatestBuildResultForProject( projectId );
352 
353         String buildAgentUrl = buildResult.getBuildUrl();
354 
355         if ( !checkBuildAgent( buildAgentUrl ) )
356         {
357             throw new BuildAgentConfigurationException( buildAgentUrl );
358         }
359 
360         if ( goals == null )
361         {
362             goals = "";
363         }
364 
365         if ( arguments == null )
366         {
367             arguments = "";
368         }
369 
370         Map<String, String> map = new HashMap<String, String>();
371 
372         if ( repository != null )
373         {
374             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY, repository.getLocation() );
375             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY_NAME, repository.getName() );
376             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY_LAYOUT, repository.getLayout() );
377         }
378 
379         try
380         {
381             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
382             String releaseId =
383                 client.releasePerformFromScm( goals, arguments, useReleaseProfile, map, scmUrl, scmUsername,
384                                               scmPassword, scmTag, scmTagBase, environments );
385 
386             addReleaseInProgress( releaseId, "perform", projectId );
387         }
388         catch ( MalformedURLException e )
389         {
390             log.error( "Invalid build agent url " + buildAgentUrl );
391             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
392         }
393         catch ( Exception e )
394         {
395             log.error( "Failed to perform release", e );
396             throw new ContinuumReleaseException( "Failed to perform release", e );
397         }
398     }
399 
400     public void releaseRollback( String releaseId, int projectId )
401         throws ContinuumReleaseException, BuildAgentConfigurationException
402     {
403         String buildAgentUrl = getBuildAgentUrl( releaseId );
404 
405         if ( !checkBuildAgent( buildAgentUrl ) )
406         {
407             throw new BuildAgentConfigurationException( buildAgentUrl );
408         }
409 
410         try
411         {
412             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
413             client.releaseRollback( releaseId, projectId );
414         }
415         catch ( MalformedURLException e )
416         {
417             log.error( "Invalid build agent url " + buildAgentUrl );
418             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
419         }
420         catch ( Exception e )
421         {
422             log.error( "Unable to rollback release " + releaseId, e );
423             throw new ContinuumReleaseException( "Unable to rollback release " + releaseId, e );
424         }
425     }
426 
427     public String releaseCleanup( String releaseId )
428         throws ContinuumReleaseException, BuildAgentConfigurationException
429     {
430         String buildAgentUrl = getBuildAgentUrl( releaseId );
431 
432         if ( !checkBuildAgent( buildAgentUrl ) )
433         {
434             throw new BuildAgentConfigurationException( buildAgentUrl );
435         }
436 
437         try
438         {
439             SlaveBuildAgentTransportClient client = new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
440             String result = client.releaseCleanup( releaseId );
441 
442             removeFromReleaseInProgress( releaseId );
443             return result;
444         }
445         catch ( MalformedURLException e )
446         {
447             log.error( "Invalid build agent url " + buildAgentUrl );
448             throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
449         }
450         catch ( Exception e )
451         {
452             log.error( "Failed to get prepared release name of " + releaseId, e );
453             throw new ContinuumReleaseException( "Failed to get prepared release name of " + releaseId, e );
454         }
455     }
456 
457     public List<Map<String, Object>> getAllReleasesInProgress()
458         throws ContinuumReleaseException, BuildAgentConfigurationException
459     {
460         List<Map<String, Object>> releases = new ArrayList<Map<String, Object>>();
461         Map<String, Map<String, Object>> releasesMap = new HashMap<String, Map<String, Object>>();
462 
463         if ( releasesInProgress != null && !releasesInProgress.isEmpty() )
464         {
465             for ( String releaseId : releasesInProgress.keySet() )
466             {
467                 String buildAgentUrl = getBuildAgentUrl( releaseId );
468 
469                 if ( StringUtils.isNotBlank( buildAgentUrl ) )
470                 {
471                     if ( !checkBuildAgent( buildAgentUrl ) )
472                     {
473                         throw new BuildAgentConfigurationException( buildAgentUrl );
474                     }
475 
476                     try
477                     {
478                         SlaveBuildAgentTransportClient client =
479                             new SlaveBuildAgentTransportClient( new URL( buildAgentUrl ) );
480                         Map map = client.getListener( releaseId );
481 
482                         if ( map != null && !map.isEmpty() )
483                         {
484                             Map<String, Object> release = releasesInProgress.get( releaseId );
485                             release.put( DistributedReleaseUtil.KEY_RELEASE_ID, releaseId );
486                             release.put( DistributedReleaseUtil.KEY_BUILD_AGENT_URL, buildAgentUrl );
487 
488                             releases.add( release );
489 
490                             releasesMap.put( releaseId, releasesInProgress.get( releaseId ) );
491                         }
492                     }
493                     catch ( MalformedURLException e )
494                     {
495                         log.error( "Invalid build agent url " + buildAgentUrl );
496                         throw new ContinuumReleaseException( "Invalid build agent url " + buildAgentUrl );
497                     }
498                     catch ( Exception e )
499                     {
500                         log.error( "Failed to get all releases in progress ", e );
501                         throw new ContinuumReleaseException( "Failed to get all releases in progress ", e );
502                     }
503                 }
504             }
505 
506             releasesInProgress = releasesMap;
507         }
508 
509         return releases;
510     }
511 
512     private Map createProjectMap( Project project )
513     {
514         Map<String, Object> map = new HashMap<String, Object>();
515 
516         map.put( DistributedReleaseUtil.KEY_PROJECT_ID, project.getId() );
517         map.put( DistributedReleaseUtil.KEY_GROUP_ID, project.getGroupId() );
518         map.put( DistributedReleaseUtil.KEY_ARTIFACT_ID, project.getArtifactId() );
519         map.put( DistributedReleaseUtil.KEY_SCM_URL, project.getScmUrl() );
520         if ( project.getProjectGroup().getLocalRepository() != null )
521         {
522             map.put( DistributedReleaseUtil.KEY_LOCAL_REPOSITORY,
523                      project.getProjectGroup().getLocalRepository().getLocation() );
524         }
525 
526         return map;
527     }
528 
529     private Map<String, String> createPropertiesMap( Properties properties )
530     {
531         Map<String, String> map = new HashMap<String, String>();
532 
533         String prop = properties.getProperty( "username" );
534         if ( prop != null )
535         {
536             map.put( DistributedReleaseUtil.KEY_SCM_USERNAME, prop );
537         }
538 
539         prop = properties.getProperty( "password" );
540         if ( prop != null )
541         {
542             map.put( DistributedReleaseUtil.KEY_SCM_PASSWORD, prop );
543         }
544 
545         prop = properties.getProperty( "tagBase" );
546         if ( prop != null )
547         {
548             map.put( DistributedReleaseUtil.KEY_SCM_TAGBASE, prop );
549         }
550 
551         prop = properties.getProperty( "commentPrefix" );
552         if ( prop != null )
553         {
554             map.put( DistributedReleaseUtil.KEY_SCM_COMMENT_PREFIX, prop );
555         }
556 
557         prop = properties.getProperty( "tag" );
558         if ( prop != null )
559         {
560             map.put( DistributedReleaseUtil.KEY_SCM_TAG, prop );
561         }
562 
563         prop = properties.getProperty( "prepareGoals" );
564         if ( prop != null )
565         {
566             map.put( DistributedReleaseUtil.KEY_PREPARE_GOALS, prop );
567         }
568 
569         prop = properties.getProperty( "arguments" );
570         if ( prop != null )
571         {
572             map.put( DistributedReleaseUtil.KEY_ARGUMENTS, prop );
573         }
574 
575         prop = properties.getProperty( "useEditMode" );
576         if ( prop != null )
577         {
578             map.put( DistributedReleaseUtil.KEY_USE_EDIT_MODE, prop );
579         }
580 
581         prop = properties.getProperty( "addSchema" );
582         if ( prop != null )
583         {
584             map.put( DistributedReleaseUtil.KEY_ADD_SCHEMA, prop );
585         }
586 
587         prop = properties.getProperty( "autoVersionSubmodules" );
588         if ( prop != null )
589         {
590             map.put( DistributedReleaseUtil.KEY_AUTO_VERSION_SUBMODULES, prop );
591         }
592 
593         return map;
594     }
595 
596     private List<PreparedRelease> getPreparedReleases()
597         throws ContinuumReleaseException
598     {
599         File file = getPreparedReleasesFile();
600 
601         if ( file.exists() )
602         {
603             FileInputStream fis = null;
604             try
605             {
606                 fis = new FileInputStream( file );
607                 ContinuumPrepareReleasesModelXpp3Reader reader = new ContinuumPrepareReleasesModelXpp3Reader();
608                 PreparedReleaseModel model = reader.read( new InputStreamReader( fis ) );
609 
610                 return model.getPreparedReleases();
611             }
612             catch ( IOException e )
613             {
614                 log.error( e.getMessage(), e );
615                 throw new ContinuumReleaseException( "Unable to get prepared releases", e );
616             }
617             catch ( XmlPullParserException e )
618             {
619                 log.error( e.getMessage(), e );
620                 throw new ContinuumReleaseException( e.getMessage(), e );
621             }
622             finally
623             {
624                 if ( fis != null )
625                 {
626                     IOUtil.close( fis );
627                 }
628             }
629         }
630 
631         return null;
632     }
633 
634     private void addReleasePrepare( String releaseId, String buildAgentUrl, String releaseName )
635         throws ContinuumReleaseException
636     {
637         File file = getPreparedReleasesFile();
638 
639         if ( !file.exists() )
640         {
641             file.getParentFile().mkdirs();
642         }
643 
644         PreparedRelease release = new PreparedRelease();
645         release.setReleaseId( releaseId );
646         release.setBuildAgentUrl( buildAgentUrl );
647         release.setReleaseName( releaseName );
648 
649         List<PreparedRelease> preparedReleases = getPreparedReleases();
650 
651         if ( preparedReleases == null )
652         {
653             preparedReleases = new ArrayList<PreparedRelease>();
654         }
655         else
656         {
657             boolean found = false;
658 
659             for ( PreparedRelease preparedRelease : preparedReleases )
660             {
661                 if ( preparedRelease.getReleaseId().equals( release.getReleaseId() ) &&
662                     preparedRelease.getReleaseName().equals( release.getReleaseName() ) )
663                 {
664                     preparedRelease.setBuildAgentUrl( release.getBuildAgentUrl() );
665                     found = true;
666                 }
667             }
668 
669             if ( !found )
670             {
671                 preparedReleases.add( release );
672             }
673         }
674 
675         PreparedReleaseModel model = new PreparedReleaseModel();
676         model.setPreparedReleases( preparedReleases );
677 
678         try
679         {
680             ContinuumPrepareReleasesModelXpp3Writer writer = new ContinuumPrepareReleasesModelXpp3Writer();
681             FileWriter fileWriter = new FileWriter( file );
682             writer.write( fileWriter, model );
683             fileWriter.flush();
684             fileWriter.close();
685         }
686         catch ( IOException e )
687         {
688             throw new ContinuumReleaseException( "Failed to write prepared releases in file", e );
689         }
690     }
691 
692     private void addReleaseInProgress( String releaseId, String releaseType, int projectId )
693     {
694         if ( releasesInProgress == null )
695         {
696             releasesInProgress = new HashMap<String, Map<String, Object>>();
697         }
698 
699         Map<String, Object> map = new HashMap<String, Object>();
700         map.put( DistributedReleaseUtil.KEY_RELEASE_GOAL, releaseType );
701         map.put( DistributedReleaseUtil.KEY_PROJECT_ID, projectId );
702 
703         releasesInProgress.put( releaseId, map );
704     }
705 
706     private void removeFromReleaseInProgress( String releaseId )
707     {
708         if ( releasesInProgress != null && releasesInProgress.containsKey( releaseId ) )
709         {
710             releasesInProgress.remove( releaseId );
711         }
712     }
713 
714     private String getBuildAgentUrl( String releaseId )
715         throws ContinuumReleaseException
716     {
717         List<PreparedRelease> preparedReleases = getPreparedReleases();
718 
719         if ( preparedReleases != null )
720         {
721             for ( PreparedRelease preparedRelease : preparedReleases )
722             {
723                 if ( preparedRelease.getReleaseId().equals( releaseId ) )
724                 {
725                     return preparedRelease.getBuildAgentUrl();
726                 }
727             }
728         }
729 
730         return null;
731     }
732 
733     private File getPreparedReleasesFile()
734     {
735         return new File( System.getProperty( "appserver.base" ) + File.separator + "conf" + File.separator +
736             PREPARED_RELEASES_FILENAME );
737     }
738 
739     private boolean checkBuildAgent( String buildAgentUrl )
740     {
741         BuildAgentConfiguration buildAgent = configurationService.getBuildAgent( buildAgentUrl );
742 
743         if ( buildAgent != null && buildAgent.isEnabled() )
744         {
745             return true;
746         }
747 
748         log.info( "Build agent: " + buildAgentUrl + "is either disabled or removed" );
749         return false;
750     }
751 }